Как получить свойства CASpringAnimation из более простого инициализатора UISpringTimingParameter?

У меня есть кривая пружинной анимации, указанная с помощью UISpringTimingParameters с коэффициент демпфирования и начальная скорость, и я использую его с UIViewPropertyAnimator с указанием его продолжительности. В другом месте моего приложения мне нужно выразить ту же анимацию, используя CASpringAnimation. Но CASpringAnimation нельзя инициализировать только коэффициентом демпфирования и InitialVelocity — для этого требуются все различные параметры пружины и определяется его settlingDuration от них.

Учитывая продолжительность, коэффициент демпфирования и начальный вектор скорости, как мне создать CASpringAnimation?


person Tom Hamming    schedule 07.04.2020    source источник


Ответы (2)


Извините, я не могу помочь вам с математикой, но, возможно, вы могли бы использовать фиктивный аниматор свойств, чтобы вычислить то, что вам нужно? См. https://developer.apple.com/videos/play/wwdc2016/216/?time=2521

func animationDuration() -> TimeInterval {
    return propertyAnimator().duration
}

func propertyAnimator(initialVelocity: CGVector = .zero) -> UIViewPropertyAnimator {
    let timingParameters = UISpringTimingParameters(mass: 4.5, stiffness: 1300, damping: 95, initialVelocity: initialVelocity)
    return UIViewPropertyAnimator(duration: assetTransitionDuration, timingParameters:timingParameters)
}
person glotcha    schedule 08.04.2020

Я нашел ответ в сообщении в блоге. Короче:

let spring = CASpringAnimation(keyPath: somePropertyPath)

//Set initial velocity and desired duration
let initialVelocity: CGFloat = desiredInitialVelocity
let relaxationTime: CGFloat = desiredDurationInSeconds

//Spring constants
let dampingRatio: CGFloat = 0.9
//Only allow damping ratio between just above 0 and 1 (critically damped)
let clippedDampingRatio: CGFloat = min(1, max(dampingRatio, 0.01))
let mass: CGFloat = 1
let fractionOfAmplitude: CGFloat = 1500 //A spring never gets to 0 amplitude, it gets infinitely smaller. This fraction represents the perceived 0 point.
let logOfFraction: CGFloat = log(fractionOfAmplitude)
let stiffness: CGFloat = (mass * pow(logOfFraction, 2)) / (pow(relaxationTime, 2) * pow(clippedDampingRatio, 2))
let angularFrequency: CGFloat = sqrt(stiffness/mass)
let damping: CGFloat = 2 * mass * angularFrequency * clippedDampingRatio

spring.initialVelocity = initialVelocity
spring.mass = mass
spring.stiffness = stiffness
spring.damping = damping
person Tom Hamming    schedule 12.05.2020