Rendering Glitch when animating CGPath From Ellipse to Rect within CAShapeLayer

43 views
Skip to first unread message

Travis Kirton

unread,
Mar 1, 2012, 4:47:54 AM3/1/12
to quart...@lists.apple.com
I am running into an issue when I create an explicit animation to change the value of a CAShapeLayer's path from an ellipse to a rect.

In my canvas controller I setup a basic CAShapeLayer and add it to the root view's 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 shape becomes a rect, and in the first few frames when it animates away from being a rect. The animation is set up 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 have tried many different things like locking / unlocking the CATransaction, playing with various fill modes, etc...

I have attached an image of the rendering glitch.

A video of what I am experiencing can be found here:



renderingglitch.png

David Duncan

unread,
Mar 1, 2012, 1:28:42 PM3/1/12
to Travis Kirton, quart...@lists.apple.com
On Mar 1, 2012, at 1:47 AM, Travis Kirton wrote:

I am running into an issue when I create an explicit animation to change the value of a CAShapeLayer's path from an ellipse to a rect.

Animating the path of a shape layer is only guaranteed to work when you are animating from like to like. A rectangle is a sequence of lines, while an ellipse is a sequence of arcs (you can see the sequence generated by using CGPathApply), and as such the animation between them isn't guaranteed to look very good, or work well at all.

To do this, you basically have to create an analog of a rectangle by using the same curves that you would use to create an ellipse, but with parameters that would cause the rendering to look like a rectangle. This shouldn't be too difficult (and again, you can use what you get from CGPathApply on the path created with CGPathAddEllipseInRect as a guide), but will likely require some tweaking to get right.
--
David Duncan

Reply all
Reply to author
Forward
0 new messages