The physics behind spring animations - Maxime Heckel's Blog
/// <https://blog.maximeheckel.com/posts/the-physics-behind-spring-animations/>
struct SpringCalculator {
private var velocity: Double
init(
velocity: Double = 0
) {
self.velocity = velocity
}
mutating func calculate(
additionalVelocity: Double = 0,
position x: Double,
time: TimeInterval = 0.2,
gravity: CGFloat = 9.8,
stiffness: CGFloat = 500,
mass: CGFloat = 20,
damping: CGFloat = 20
) -> CGFloat {
velocity += additionalVelocity
/* Spring stiffness, in kg / s^2 */
let k: CGFloat = stiffness
let fg = mass * gravity
let fa = -k * x
/* Damping constant, in kg / s */
let fd = -damping * velocity
// Accelleration
let a = (fa + fd + fg) / mass
let vy = velocity + a * time
velocity = vy
// New position
let newValue = x + vy * time
return newValue
}
}