我在 iOS 中很好地沿着 CGPath (QuadCurve) 制作了 CALayer 动画。但我想使用比少数更有趣的缓动函数 由 Apple 提供(EaseIn/EaseOut 等)。例如,弹跳或弹性函数。
这些事情可以用 MediaTimingFunction (贝塞尔曲线)来完成:
但我想创建 更复杂的计时功能。问题是媒体计时似乎需要三次贝塞尔曲线,但其功能不足以创建这些效果:
(来源:sparrow-framework.org)
要创建的代码上面的内容在其他框架中已经足够简单了,这使得这非常令人沮丧。请注意,这些曲线是将输入时间映射到输出时间(Tt 曲线),而不是时间-位置曲线。例如,easeOutBounce(T) = t 返回一个新的t。然后,t 用于绘制运动(或我们应该设置动画的任何属性)。
所以,我想创建一个复杂的自定义 CAMediaTimingFunction
但我不知道如何做到这一点,或者是否可能?有其他选择吗?
编辑:
这是步骤的具体示例。非常有教育意义 :)
-
我想沿着从点 a 到 b 的直线为对象设置动画,但我希望它使用以下命令“弹跳”沿直线的运动上面的 easyOutBounce 曲线。这意味着它将沿着从 a 到 b 的精确路线,但会以比当前基于贝塞尔曲线的 CAMediaTimingFunction 更复杂的方式加速和减速。
-
让我们使该线成为由 CGPath 指定的任意曲线移动。它仍应沿着该曲线移动,但应以与直线示例中相同的方式加速和减速。
理论上我认为它应该像这样工作:
让我们将运动曲线描述为关键帧动画 move(t) = p,其中 t 是时间 [0..1] ,p是在时间t计算的位置。因此,move(0) 返回曲线起点的位置,move(0.5) 返回曲线的中间位置,move(1) 返回曲线末尾的位置。使用计时函数 time(T) = t 为 move 提供 t 值应该可以满足我的需求。对于弹跳效果,计时函数应为 time(0.8) 和 time(0.8) 返回相同的 t 值(仅作为示例) 。只需更换定时功能即可得到不同的效果。
(是的,可以通过创建和连接四个来回的线段来进行线弹跳,但这不是必需的。毕竟,它只是一个映射时间的简单线性函数价值观与职位。)
我希望我在这里说得有道理。
I am animating a CALayer
along a CGPath
(QuadCurve) quite nicely in iOS. But I'd like to use a more interesting easing function than the few provided by Apple (EaseIn/EaseOut etc). For instance, a bounce or elastic function.
These things are possible to do with MediaTimingFunction (bezier):
But I'd like to create timing functions that are more complex. Problem is that media timing seems to require a cubic bezier which is not powerful enough to create these effects:
(source: sparrow-framework.org)
The code to create the above is simple enough in other frameworks, which makes this very frustrating. Note that the curves are mapping input time to output time (T-t curve) and not time-position curves. For instance, easeOutBounce(T) = t returns a new t. Then that t is used to plot the movement (or whatever property we should animate).
So, I'd like to create a complex custom CAMediaTimingFunction
but I have no clue how to do that, or if it's even possible? Are there any alternatives?
EDIT:
Here is a concrete example in to steps. Very educational :)
-
I want to animate an object along a line from point a to b, but I want it to "bounce" its movement along the line using the easeOutBounce curve above. This means it will follow the exact line from a to b, but will accelerate and decelerate in a more complex way than what is possible using the current bezier-based CAMediaTimingFunction.
-
Lets make that line any arbitrary curve movement specified with CGPath. It should still move along that curve, but it should accelerate and decelerate the same way as in the line example.
In theory I think it should work like this:
Lets describe the movement curve as a keyframe animation move(t) = p, where t is time [0..1], p is position calculated at time t. So move(0) returns the position at the start of curve, move(0.5) the exact middle and move(1) at end. Using a an timing function time(T) = t to provide the t values for move should give me what I want. For a bouncing effect, the timing function should return the same t values for time(0.8) and time(0.8) (just an example). Just replace the timing function to get a different effect.
(Yes, it's possible to do line-bouncing by creating and joining four line segments which goes back and forth, but that shouldn't be necessary. After all, it's just a simple linear function which maps time values to positions.)
I hope I'm making sense here.
发布评论
评论(6)
我发现了这个:
Cocoa with Love - Core Animation 中的参数化加速曲线
但我认为通过使用块可以使其变得更简单且更具可读性。因此,我们可以在 CAKeyframeAnimation 上定义一个类别,如下所示:
CAKeyframeAnimation+Parametric.h:
CAKeyframeAnimation+Parametric.m:
现在用法将如下所示:
我知道它可能不像您想要的那么简单,但它是一个开始。
I found this:
Cocoa with Love - Parametric acceleration curves in Core Animation
But I think it can be made a little simpler and more readable by using blocks. So we can define a category on CAKeyframeAnimation that looks something like this:
CAKeyframeAnimation+Parametric.h:
CAKeyframeAnimation+Parametric.m:
Now usage will look something like this:
I know it might not be quite as simple as what you wanted, but it's a start.
从 iOS 10 开始,可以使用两个新的计时对象更轻松地创建自定义计时功能。
1) UICubicTimingParameters 允许定义三次贝塞尔曲线作为缓动函数。
或者只是在动画师初始化时使用控制点
这个很棒的服务将帮助您为曲线选择控制点。
2) UISpringTimingParameters 让开发者可以操纵阻尼比,< em>质量、刚度和初始速度来创建所需的弹簧行为。
持续时间参数仍然存在于 Animator 中,但对于弹簧计时将被忽略。
如果这两个选项还不够,您还可以通过确认 UITimingCurveProvider 协议来实现您自己的时序曲线。
更多详细信息,如何使用不同的计时参数创建动画,您可以在文档中找到。
另外,请参阅 WWDC 2016 的UIKit 动画和过渡演示的进展。
From iOS 10 it became possible to create custom timing function easier using two new timing objects.
1) UICubicTimingParameters allows to define cubic Bézier curve as an easing function.
or simply using control points on animator initialization
This awesome service is going to help to choose control points for your curves.
2) UISpringTimingParameters lets developers manipulate damping ratio, mass, stiffness, and initial velocity to create desired spring behavior.
Duration parameter is still presented in Animator, but will be ignored for spring timing.
If these two options are not enough you also can implement your own timing curve by confirming to the UITimingCurveProvider protocol.
More details, how to create animations with different timing parameters, you can find in the documentation.
Also, please, see Advances in UIKit Animations and Transitions presentation from WWDC 2016.
创建自定义计时函数的一种方法是使用 CAMediaTimingFunction 中的 functionWithControlPoints:::: 工厂方法(还有相应的 initWithControlPoints:::: init 方法)。它的作用是为您的计时函数创建一条贝塞尔曲线。它不是一条任意曲线,但贝塞尔曲线非常强大且灵活。需要一些练习才能掌握控制点。提示:大多数绘图程序都可以创建贝塞尔曲线。玩这些会给你一个关于你用控制点表示的曲线的视觉反馈。
此链接指向苹果的文档。有一个简短但有用的部分介绍了如何从曲线构建预构建函数。
编辑:
以下代码显示了一个简单的弹跳动画。为此,我创建了一个组合计时函数(values 和 timing NSArray 属性),并为动画的每个片段指定了不同的时间长度(keytimes > 财产)。通过这种方式,您可以组合贝塞尔曲线来组合更复杂的动画时序。 这是一篇关于此的好文章带有很好的示例代码的动画类型。
A way to create a custom timing function is by using the functionWithControlPoints:::: factory method in CAMediaTimingFunction (there is a corresponding initWithControlPoints:::: init method as well). What this does is create a Bézier curve for your timing function. It is not an arbitrary curve, but Bézier curves are very powerful and flexible. It takes a little practice to get the hang of the control points. A tip: most drawing programs can create Bézier curves. Playing with those will give you a visual feedback on the curve you are representing with the control points.
The this link points to apple's documentation. There is a short but useful section on how the pre-build functions are constructed from curves.
Edit:
The following code shows a simple bounce animation. For doing so, I created a composed timing function (values and timing NSArray properties) and gave each segment of the animation a different time length (keytimes property). In this way you can compose Bézier curves to compose more sophisticated timing for animations. This is a good article on this type of animations with a nice sample code.
不确定您是否还在寻找,但 PRTween 看起来相当令人印象深刻,因为它的能力超越了Core Animation 为您提供开箱即用的功能,最值得注意的是,自定义计时功能。它还附带了许多(如果不是全部)各种 Web 框架提供的流行缓动曲线。
Not sure if you're still looking, but PRTween looks fairly impressive in terms of its ability to go beyond what Core Animation gives you out of the box, most notably, custom timing functions. It also comes packaged with many—if not all—of the popular easing curves that various web frameworks provide.
一个 swift 版本的实现是 TFAnimation。该演示是一个罪孽曲线动画。使用
TFBasicAnimation
就像CABasicAnimation
一样,除了用timingFunction
以外的块分配timeFunction
。关键点是子类
CAKeyframeAnimation
并通过timeFunction
以1 / 60fps
s 的间隔计算帧位置。将所有计算值添加到CAKeyframeAnimation
的 >values 以及keyTimes
的时间间隔。A swift version implementation is TFAnimation.The demo is a sin curve animation.Use
TFBasicAnimation
just likeCABasicAnimation
except assigntimeFunction
with a block other thantimingFunction
.The key point is subclass
CAKeyframeAnimation
and calculate frames position bytimeFunction
in1 / 60fps
s interval .After all add all the calculated value tovalues
ofCAKeyframeAnimation
and the times by interval tokeyTimes
too.我创建了一种基于块的方法,它生成一个具有多个动画的动画组。
每个属性的每个动画都可以使用 33 种不同参数曲线中的一种、具有初始速度的衰减计时函数或根据您的需求配置的自定义弹簧。
生成组后,它会缓存在视图上,并且可以使用 AnimationKey 触发,无论是否有动画。一旦触发,动画就会相应地同步表示层的值,并相应地应用。
该框架可以在这里找到 FlightAnimator
下面是一个示例:
触发动画
I created a blocks based approach, that generates an animation group, with multiple animations.
Each animation, per property, can use 1 of 33 different parametric curves, a Decay timing function with initial velocity, or a custom spring configured to your needs.
Once the group is generated, it's cached on the View, and can be triggered using an AnimationKey, with or without the animation. Once triggered the animation is synchronized accordingly the presentation layer's values, and applied accordingly.
The framework can be found here FlightAnimator
Here is an example below:
To trigger the animation