Search code examples
objective-cquartz-corecakeyframeanimationnsbezierpath

How do I control animation timing along a NSBezier path?


In Apple's docs about CAKeyframeAnimation they say:

"For most types of animations, you specify the keyframe values using the values and keyTimes properties. During the animation, Core Animation generates intermediate values by interpolating between the values you provide. When animating a value that is a coordinate point, such as the layer’s position, you can specify a path for that point to follow instead of individual values. The pacing of the animation is controlled by the timing information you provide."

enter image description here

What I want to do is to make an animation of an image along the path above while controlling the timing. More specific, the path starts at (0,0) and goes to (100,0) during 1 sec, then follows a half-circle path to point (300,0) during 3 sec, and the goes to point (400,0) during 1 sec.

I have already definied this path as a NSBezier path and I can make the animation, but I don't know how to control the timing of the different parts of the path. From Apple's docs it seems that this should be possible, but how?


Solution

  • There is a simple solution. The only thing you have to choose are the points on your path that you want to use for time control. In my case I have 4 points p0=(0,0), p1=(100,0), p2 =(200,0), and p3 =(300,0). I then use

    animation.values = @[[NSValue valueWithPoint:p0],
                                   [NSValue valueWithPoint:p1],
                                   [NSValue valueWithPoint:p2],
                                   [NSValue valueWithPoint:p3]];
    
    animation.keyTimes = @[@0.0, @0.2, @0.8, @1.0];
    

    The fact that we are using a half circle (or any other complicated) path DOES NOT have any influence (as long as it doesn't cross itself). You just choose some points on the path, use them to define animation.values, and then choose (relative) times for those points and use them to define animation.keyTimes. That's all, really.