Keyframe Animation
I have been doing some keyframe animations lately and figured it would make a good entry.
Keyframe animations are cool because they give you more exact control over the way your layers animate. The basic animation does a linear interpolation between the 'start' value and the 'end' value. Which works great in many if not most cases but some times you want the path your animation follows to be something different or more sophisticated. The keyframe allows you full control over the intermediate values of the animation.
Whereas the basic animation does a simple linear interpolation the keyframe allows you to specify values at intermediate times so that you can fully control the value during the whole animation. Keyframes have played a part in animation since the days of hand drawn movies. Senior artists would draw the 'key frames' for a scene and then junior artists would fill in the required frames to make the animation smooth (sometimes this process is called tweening). The keyframe animation takes care of the tweening for us we specify the 'key frames' and it does the rest.
Another cool thing is the 'value' that the keyframe can animate is anything that the basic animation can animate. Specifically that boils down to any property of types number, point, size or rect. So for example if we wanted to animate the opacity of a layer we could specify several different values (i.e. 0.25, 0.50, 0.75) that should be reached at specific times during the animation. The keyframe animation would then interpolate between each of the values that we specify.
Another aspect that is really cool is that we can use CGPath's to specify the values instead of discrete values. In other words instead of specific values at specific time points we can use a path to specify the values. For example we could animate the opacity of a layer with a bell curve, start transparent, fade up to some opacity value and then fade back. We can also use the paths to animate CGPoint and CGSize values. In this case the x value of the path becomes either the x or width value and y becomes the y or height values.
In the example we will have a layer move back and forth across the window. Here is a screen shot of the app running.
The white line is a bezier path that we are using to animate the movie layer across the screen. Its drawn simply so we can see it in greater detail. Here is the code used to create the path.
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, _point1.x + _movieSize.width * 0.5f, _point1.y);
CGPathAddCurveToPoint(path, NULL, _controlPoint1.x + _movieSize.width * 0.5f,
_controlPoint1.y, _controlPoint2.x - _movieSize.width * 0.5f,
_controlPoint2.y, _point2.x - _movieSize.width * 0.5f, _point2.y);
if(NULL != _rightBoundKeyframePath) {
CGPathRelease(_rightBoundKeyframePath);
}
_rightBoundKeyframePath = CGPathCreateCopy(path);
CGPathRelease(path);
path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, _point2.x - _movieSize.width * 0.5f, _point2.y);
As you can see it straight Quartz path creation code. We then place that path into a keyframe animation like this;
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.duration = 2.0f;
if(YES == _atLeftEdge) {
animation.path = _rightBoundKeyframePath;
// the rotation mode causes the layer to rotate along with the slope of the path
animation.rotationMode = kCAAnimationRotateAuto;
} else {
animation.path = _leftBoundKeyframePath;
// since the path is reversed, rotate at 180 degrees off
animation.rotationMode = kCAAnimationRotateAutoReverse;
}
_movieLayer.actions = [NSDictionary dictionaryWithObject:animation forKey:@"position"];
Now when ever the position of the layer is changed it will follow the path instead of the default linear interpolation. There is a lot more to be said here but this at least gives a quick intro do using the keyframe animation. Here is the code.
Have Fun!
Permalink 3 Comments - Add Yours


