Time Warp in Animation

CAMediaTiming Protocol offers a small set of eight properties. But it is sufficient to do all kinds of time warps, if you know what exactly every property means and how to use it.

The most used and simple one is duration:

duration
Specifies the basic duration of the animation, in seconds.

Nothing needs further explanation here.

The duration you specify may differ from the real duration you experience, depending on the parent time space or speed:

speed
Specifies how time is mapped to receiver’s time space from the parent time space.

So an animation with duration of 1 second and speed of 1 is the same as an animation with duration of 2 seconds and speed of 2, when mapped to real time space.

The two repeating properties — repeatCount and repeatDuration — are as clear as they are named. So is autoreverses.

Finally, we are talking about the three interesting but not intuitive properties:

beginTime

beginTime
Specifies the begin time of the receiver in relation to its parent object, if applicable.

If an animation is in an animation group, beginTime is the offset from the beginning of its parent object — the animation group. So if beginTime of the animation is 5, it begins 5 seconds after the animation group begins.

If an animation is added directly to a layer, beginTime is still the offset from the beginning of its parent object — the layer. But since the beginning of a layer is in the past1, I can not simply set beginTime to 5 to delay the animation 5 seconds, because 5 seconds after the beginning of a layer is probably still a past time. What I usually really want is a delay relative to when the animation is added to the layer — denoted by addTime. So

animation.beginTime=addTime+delay;

In order to get addTime, I can use CACurrentMediaTime and convertTime:fromLayer::

addTime=[layerconvertTime:CACurrentMediaTime()fromLayer:nil];

If beginTime of the layer itself is to be set, addTime must be calculated after it is set because beginTime shifts the time space of the layer.