Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate the drawing of a CGPath?

I am wondering if there is a way to do this using Core Animation. Specifically, I am adding a sub-layer to a layer-backed custom NSView and setting its delegate to another custom NSView. That class's drawInRect method draws a single CGPath:

- (void)drawInRect:(CGRect)rect inContext:(CGContextRef)context
{
    CGContextSaveGState(context);
    CGContextSetLineWidth(context, 12);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, rect.size.width, rect.size.height);

    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}

My desired effect would be to animate the drawing of this line. That is, I'd like for the line to actually "stretch" in an animated way. It seems like there would be a simple way to do this using Core Animation, but I haven't been able to come across any.

Do you have any suggestions as to how I could accomplish this goal?

like image 757
Jordan Kay Avatar asked Apr 04 '10 22:04

Jordan Kay


1 Answers

I found this animated paths example and wanted to share it for anyone else looking for how to do this with some code examples.

You will be using CAShapeLayer's strokeStart and strokeEnd which requires sdk 4.2, so if you are looking to support older iOS SDKs unfortunately this isn't what you want.

The really nice thing about these properties is that they are animatable. By animating strokeEnd from 0.0 to 1.0 over a duration of a few seconds, we can easily display the path as it is being drawn:

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 10.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.pathLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];

Finally, add a second layer containing the image of a pen and use a CAKeyframeAnimation to animate it along the path with the same speed to make the illusion perfect:

CAKeyframeAnimation *penAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
penAnimation.duration = 10.0;
penAnimation.path = self.pathLayer.path;
penAnimation.calculationMode = kCAAnimationPaced;
[self.penLayer addAnimation:penAnimation forKey:@"penAnimation"];

Which the source can be viewed here and a demo video here. Read the creators blog for more information.

like image 90
John Riselvato Avatar answered Oct 09 '22 20:10

John Riselvato