CAShapeLayer Animation Paths Glyphs / Flicker (from ellipse to straight and vice versa)

I have a problem when I create an explicit animation to change the value of the CAShapeLayer path from ellipse to rectangle.

In my canvas controller, I set the base CAShapeLayer and add it to the root view layer:

CAShapeLayer *aLayer; aLayer = [CAShapeLayer layer]; aLayer.frame = CGRectMake(100, 100, 100, 100); aLayer.path = CGPathCreateWithEllipseInRect(aLayer.frame, nil); aLayer.lineWidth = 10.0f; aLayer.strokeColor = [UIColor blackColor].CGColor; aLayer.fillColor = [UIColor clearColor].CGColor; [self.view.layer addSublayer:aLayer]; 

Then, when I animate the path, I get a strange glitch / flicker in the last few frames of the animation when the figure becomes straight, and in the first few frames when it animates away from the straight. The animation is configured as follows:

 CGPathRef newPath = CGPathCreateWithRect(aLayer.frame, nil); [CATransaction lock]; [CATransaction begin]; [CATransaction setAnimationDuration:5.0f]; CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"path"]; ba.autoreverses = YES; ba.fillMode = kCAFillModeForwards; ba.repeatCount = HUGE_VALF; ba.fromValue = (id)aLayer.path; ba.toValue = (__bridge id)newPath; [aLayer addAnimation:ba forKey:@"animatePath"]; [CATransaction commit]; [CATransaction unlock]; 

I tried a lot of different things, such as locking / unlocking CATransaction, playing with different fill modes, etc.

Here's a breakdown image: http://www.postfl.com/outgoing/renderingglitch.png

A video of what I'm experiencing can be found here: http://vimeo.com/37720876

+7
source share
2 answers

Unfortunately, this limitation is an otherwise surprising property of the animated path for CAShapeLayers.

It basically tries to interpolate between two paths. It gets into a problem when the destination path and the start path have a different number of control points, and curves and straight edges will have this problem.

You can try to minimize the effect by drawing an ellipse as 4 curves instead of a single ellipse, but this is still not entirely correct. I did not find a way to smoothly transition from curves to polygons.

You can get most of the way, and then go on to the fade animation for the last part - it will not look so good.

+5
source

I got this feedback from the quartz-dev list:

David Duncan wrote:

Animating the path of a shape layer is only guaranteed when you animate as you like. A rectangle is a sequence of lines, and an ellipse is a sequence of arcs (you can see the sequence generated using CGPathApply), and thus the animation between them is not guaranteed that they look very good or even work well.

To do this, you basically need to create an analog of a rectangle using the same curves that you would use to create an ellipse, but with parameters that will make the rendering look like a rectangle. This should not be too complicated (and, again, you can use what you get from CGPathApply on the path created with CGPathAddEllipseInRect as a guide), but it will probably take some tweaking to get it right.

+6
source

All Articles