5

鉴于[UIView animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:]中使用的弹簧参数:

  1. 使用SpringWithDamping
  2. 初始SpringVelocity

时间与位置图的数学方程是什么?

(我正在尝试处理 iOS 7 中新的 spring 动画 API,但我没有得到好的结果,而且实验花费的时间太长。我的目标是尽可能接近我的一些动画曲线如果我使用核心动画而不是 UIView 的块对象动画,我会指定使用 CAMediaTimingFunction。)

4

3 回答 3

8

阻尼比

弹簧动画接近其静止状态时的阻尼比。

要使动画平稳减速而没有振荡,请使用值 1。使用接近零的阻尼比来增加振荡。

随着阻尼值接近 0.0,弹簧变得更有弹性。

速度

初始弹簧速度。为了平滑地开始动画,将此值与视图的速度相匹配,因为它在附加之前。

初始弹簧速度的值 1.0 对应于一秒内遍历的总动画距离。例如,如果总动画距离为 200 点,并且您希望动画的开始与 100 pt/s 的视图速度相匹配,则使用值 0.5。

例子:

[UIView animateWithDuration:2.0
                      delay:0.0
     usingSpringWithDamping:0.4
      initialSpringVelocity:0.5
                    options:(UIViewAnimationOptions)options
                 animations:^{

                 }
                completion:nil];

在此处输入图像描述

于 2015-06-10T08:59:51.203 回答
1

我相信由此产生的数学方程是这里描述的:http ://en.wikipedia.org/wiki/Damping

阻尼参数对应于阻尼比 ζ,并且 ζ = 1 导致所谓的临界阻尼弹簧,它会尽可能快地收敛到最终位置而不会振荡。初始速度为零时,它对应于类似缓入缓出曲线,但缓入部分更陡峭,缓出部分更平滑。

对于大于 1 的阻尼比,动画看起来更线性。对于阻尼比小于最终位置的振荡将出现。它的频率可以从动画持续时间和可能的其他参数中得出。

以下是文档关于初始速度的说法,应该很清楚:

初始弹簧速度。为了平滑地开始动画,将此值与视图的速度相匹配,因为它在附加之前。值 1 对应于一秒内遍历的总动画距离。例如,如果总动画距离为 200 点,并且您希望动画的开始与 100 pt/s 的视图速度相匹配,则使用值 0.5。

于 2014-02-26T10:42:39.257 回答
1

iOS中主要有四种spring API:

  • SwiftUI Animation.spring(response:dampingFraction:blendDuration:)
  • SwiftUI Animation.interpolatingSpring(质量:刚度:阻尼:初始速度:)
  • UIView.animate(withDuration:延迟:usingSpringWithDamping:initialSpringVelocity:选项:动画:完成:)
  • CASpringAnimation(具有 4 个物理属性:质量、刚度、阻尼、初始速度)

它们基于相同的物理过程,因此具有相同的基本方程,可以写为

func curveFunc(_ t: Double) -> Double {
    let v0 = initialVelocity
    let zeta = dampingRatio

    let y: Double
    if abs(zeta - 1.0) < 1e-8 {
        let c1 = -1.0
        let c2 = v0 - omega
        y = (c1 + c2 * t) * exp(-omega * t)
    } else if zeta > 1 {
        let s1 = omega * (-zeta + sqrt(zeta * zeta - 1))
        let s2 = omega * (-zeta - sqrt(zeta * zeta - 1))
        let c1 = (-s2 - v0) / (s2 - s1)
        let c2 = (s1 + v0) / (s2 - s1)
        y = c1 * exp(s1 * t) + c2 * exp(s2 * t)
    } else {
        let a = -omega * zeta
        let b = omega * sqrt(1 - zeta * zeta)
        let c2 = (v0 + a) / b
        let theta = atan(c2)
        // Alternatively y = (-cos(b * t) + c2 * sin(b * t)) * exp(a * t)
        y = sqrt(1 + c2 * c2) * exp(a * t) * cos(b * t + theta + Double.pi)
    }

    return y + 1
}

共有三个参数initialVelocitydampingRatioomegadampingRatio决定曲线的形状,dampingRatio为0时为无阻尼谐振子,越大dampingRatio表示摩擦力越大。使用 SwiftUI Animation.spring,你可以拥有dampingRatio大于 1 的 a,而使用其他三个你不能的 API。omega是没有阻尼时的角频率,越大omega意味着振荡越快。

t是以秒为单位的时间。该函数的返回值是相对的:0表示动画的起点,1表示动画的终点。initialVelocity也是相对的。值 1 对应于一秒内遍历的总动画距离。

四种不同的 API 有不同的方法来确定这三个参数。

(1) 在 Animation.spring API 中,

欧米茄 = 2 * π / 响应,

初始速度 = 0,

阻尼比只是阻尼分数。

(2) 在 Animation.interpolatingSpring API 中,

omega = sqrt(刚度/质量),

阻尼比 = min(1.0, 阻尼 / 2 / sqrt(刚度 * 质量))

(3)在UIView.animate API中,dampingRatio只是initialVelocity在API的参数中,但dampingRatio不允许大于1。是从参数omega中计算出来的。duration如果dampingRatio == 1,omega是这样的值

abs(-1 + (v0 - omega) * 持续时间) * exp(-omega * 持续时间) == 0.001。

如果dampingRatio < 1,omega是这样的值

abs(c2) * exp(a * t) == 0.001,

其中c2a定义curveFunc如上所示。

(4) CASpringAnimation 同(2)。

我编写了一个项目github.com/CosynPa/RevealSpringAnimation来模拟系统弹簧动画。如果您想查看更多详细信息,请查看它。

于 2021-02-27T15:11:44.740 回答