How to animate an non-closed path with CAShapeLayer?
- by mystify
On GitHub you can find an example for CAShapeLayer which animates an path. It animates a pentagon turning into a star.
First: This works only in the iPhone simulator. OS 3.0 on the device shows serious bugs with this code. But I can't find anything wrong in there.
However, I tried to animate an path which is not closed. To put it simply: A few straight lines.
Is there anything special I must do to get this work properly on the device?
- (void)loadView
{
UIView *appView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
appView.backgroundColor = [UIColor blackColor];
self.view = appView;
[appView release];
rootLayer = [CALayer layer];
rootLayer.frame = self.view.bounds;
[self.view.layer addSublayer:rootLayer];
//Pentagon Path
pentagonPath = CGPathCreateMutable();
CGPathMoveToPoint(pentagonPath, nil, 10.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 100.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 110.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 120.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 130.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 310.0f, 270.0f);
//CGPathCloseSubpath(pentagonPath);
//Star Path
starPath = CGPathCreateMutable();
CGPathMoveToPoint(starPath, nil, 10.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 100.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 210.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 220.0f, 260.0f);
CGPathAddLineToPoint(starPath, nil, 230.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 310.0f, 270.0f);
//CGPathCloseSubpath(starPath);
//Create Shape
shapeLayer = [CAShapeLayer layer];
//shapeLayer.path = pentagonPath;
UIColor *col = [UIColor colorWithWhite:0.9 alpha:1.0];
//shapeLayer.fillColor = col.CGColor;
shapeLayer.strokeColor = col.CGColor;
shapeLayer.lineWidth = 3.0f;
// shapeLayer.contents = [UIImage imageNamed:@"test.png"];
shapeLayer.fillRule = kCAFillRuleEvenOdd;
[rootLayer addSublayer:shapeLayer];
[self performSelector:@selector(startAnimation) withObject:nil afterDelay:1.0];
}
-(void)startAnimation
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 2.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.repeatCount = 1e100f;
animation.autoreverses = YES;
animation.fromValue = (id)pentagonPath;
animation.toValue = (id)starPath;
[shapeLayer addAnimation:animation forKey:@"animatePath"];
}
Note this lines, where I just make straight lines with a small peak which is animated:
//Pentagon Path
pentagonPath = CGPathCreateMutable();
CGPathMoveToPoint(pentagonPath, nil, 10.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 100.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 110.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 120.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 130.0f, 270.0f);
CGPathAddLineToPoint(pentagonPath, nil, 310.0f, 270.0f);
//CGPathCloseSubpath(pentagonPath);
//Star Path
starPath = CGPathCreateMutable();
CGPathMoveToPoint(starPath, nil, 10.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 100.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 210.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 220.0f, 260.0f);
CGPathAddLineToPoint(starPath, nil, 230.0f, 270.0f);
CGPathAddLineToPoint(starPath, nil, 310.0f, 270.0f);
I don't want a closed and filled path, but only simple lines with some color and thickness. The nasty thing on the device is, that the first point seems to move towards the right side of the screen for no reason. On the simulator though, it works perfectly fine. Maybe something is wrong with this setup?