How do the parameters of interpolatingSpring() work

72 Views Asked by At

I am trying to build a spring animation in SwiftUI that can carry over the velocity of a pan gesture. For this I am using the following initializer.

static func interpolatingSpring(
    mass: Double = 1.0,
    stiffness: Double,
    damping: Double,
    initialVelocity: Double = 0.0
) -> Animation

However, I don't really understand how the initialVelocity really changes the animation. I have made a small experimental Playground project below.

import SwiftUI

struct ContentView: View {
    @State var pos: CGFloat = 40
    
    var body: some View {
        Circle()
            .frame(width: 50)
            .position(x: pos, y: 350)
            .onTapGesture {
                withAnimation(.interpolatingSpring(stiffness: 2500, damping: 600, initialVelocity: 60)) {
                    if pos == 40 {
                        pos = 340
                    } else {
                        pos = 40
                    }
                }
            }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

From experementing with different values I have found that if you want to increase initialVelocity above a given treshold, no matter how much you increase the damping, it won't be enough to stop it from bouncing. If you want to go with a high initialVelocity, you also have to increase the stiffness and play around with that as damping seems to be clamped(?) somehow to the stifness.

I would be greatly thankful for someone that can shed some light on how these properties actually relate to one another as the documenation is very scarce. For example, it goes on to mention that initialVelocity should be in the range [0,1], but that does not seem to be the case...

To really sum up my question: How can I achieve criticial damping with a non-zero initialVelocity value? It's easy to calculate damping value for a critically damped spring and a given stiffnes, but this equation gets thrown-off when a non-zero initialVelocity is introduced.

Also, I would really appreciate if someone could help figure out how to get a valid initialVelocity value out of a pan gesture.

Thanks!

0

There are 0 best solutions below