在Cocoa / Touch中,CAMediaTimingFunction表示四个控制点,指定计时函数的三次贝塞尔曲线。对于我正在编写的应用程序,我希望能够在任意时间t(0 - > 1)提取所述贝塞尔曲线的结果。令我困惑的是,当我查看如何do this时,结果应该是一个点,而不是标量:
然而,Apple的实现会产生一个标量值(你可以在这个图上看到他们绘制的x(t)vs t:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/Timing.html#//apple_ref/doc/uid/TP40006670-SW1)
那么Apple是否只是忽略结果的y坐标而只处理x?这看起来很奇怪,因为那时你不需要传递控制点,而是控制标量,因为y不会影响结果。
答案 0 :(得分:11)
CoreAnimation的CAMediaTimingFunction
可以满足您的需要,但不会为给定的'x'提供'y'用于多功能(动画)使用,而只是将解决的值不透明地提供给引擎盖下的动画系统。
RSTimingFunction *heavyEaseInTimingFunction = [RSTimingFunction timingFunctionWithControlPoint1:CGPointMake(0.8, 0.0) controlPoint2:CGPointMake(1.0, 1.0)];
CGFloat visualProgress = [heavyEaseInTimingFunction valueForX:progress];
您可以使用a cubic Bézier curve创建轻松,轻松,轻松自如或任何可以描述的曲线。实现数学基于WebCore(WebKit),这可能是CoreAnimation在引擎盖下使用的。
享受, 圣拉斐尔
答案 1 :(得分:4)
注意:我不是CoreAnimation的专家。这只是我通过阅读您链接的文档的理解。
Apple正在混合坐标系统,这造成了一些混乱。
示例图中的 x(t)
表示沿某条路径的标量进度,而不是物理坐标。
CAMediaTimingFunction中使用的控制点用于描述此进程,而不是几何点。为了增加混淆,控制点中的x
实际上映射到图上的t
,并且控制点中的y
映射到图上的x(t)
。
以kCAMediaTimingFunctionEaseInEaseOut
的情节为例,该图将由控制点(0,0),(0.5,0),(0.5,1),(1,1)粗略描述。
答案 2 :(得分:2)
这很不幸,但Core Animation没有为其动画时序公开其内部计算模型。然而,对我来说非常有用的是使用Core Animation来完成这项工作!
CALayer
以充当评估者((0.0, 0.0), (1.0, 1.0))
isHidden
设为true
speed
设为0.0
如果要评估任何CAMediaTimingFunction
,请创建参考动画:
let basicAnimation = CABasicAnimation(keyPath: "bounds.origin.x")
basicAnimation.duration = 1.0
basicAnimation.timingFunction = timingFunction
basicAnimation.fromValue = 0.0
basicAnimation.toValue = containerLayer.bounds.width
referenceLayer.add(basicAnimation, forKey: "evaluatorAnimation")
将参考图层的timeOffset
设置为您要评估的任何规范化输入值(即0.0
和1.0
之间):
referenceLayer.timeOffset = 0.3 // 30% into the animation
询问参考图层的表示层,并获取其当前边界的原点x值:
if let presentationLayer = referenceLayer.presentation() as CALayer? {
let evaluatedValue = presentationLayer.bounds.origin.x / containerLayer.bounds.width
}
基本上,您正在使用Core Animation为不可见的图层运行动画。但是图层的speed
是0.0
,因此它根本不会进展动画。使用timeOffset
,我们可以手动调整动画的当前位置,然后获取其表示层的x位置。这表示由动画驱动的该属性的当前感知值。
这有点不同寻常,但没有任何关于它的hacky。它是忠实的CAMediaTimingFunction
输出值的表示,因为Core Animation实际上正在使用它。
唯一需要注意的是,表现层与屏幕上显示的值接近近似。核心动画并不保证其准确性,但在我使用核心动画的这些年里,我从未见过它是不准确的。尽管如此,如果您的应用程序需要绝对准确,那么这种技术可能不是最好的。
答案 3 :(得分:1)
WebKit源代码中的最佳提示可能是UnitBezier.h。事实上,我猜Apple在Core Animation中使用相同的代码。
更长,他们使用计算参数t
(与时间无关)给定值x
实际包含时间值。然后他们使用Newton-Raphson method(additional explanation with examples)。由于它可能会失败,因此它们会再次使用二分法(“分而治之”)。请参阅solveCurveX()
方法。
在获得参数t
之后(鉴于参数定义了三次贝塞尔曲线,这是必要的),他们只是用它来计算y
。请参阅solve()
方法。
顺便说一句,卡布奇诺的忠实粉丝,仍然希望释放阿特拉斯: - )