Search code examples
cocoacore-animationquartz-graphicscgpath

The transform property in CGPathAddEllipseInRect


I am using CGPathAddEllipseInRect to draw a circle and then using that in CAKeyframeAnimation. My issue is that the animation always starts in the same spot. I thought that I could do the following with a CGAffineTransform to make it start in a different point:

CGAffineTransform temp = CGAffineTransformMakeRotation(M_PI / 2);
CGPathAddEllipseInRect(animationPath , &temp, rect);

I do not know what this is doing. When it runs, I don't even see this portion of the animation. It is doing something offscreen. Any help understanding this would be great.


Solution

  • The rotation happens around the origin (0,0) by default, but you want to rotate around the center of the circle, so you have to do additional transformations:

    float midX = CGRectGetMidX(rect);
    float midY = CGRectGetMidY(rect);
    CGAffineTransform t = 
        CGAffineTransformConcat(
            CGAffineTransformConcat(
                CGAffineTransformMakeTranslation(-midX, -midY), 
                CGAffineTransformMakeRotation(angle)), 
            CGAffineTransformMakeTranslation(midX, midY));
    CGPathAddEllipseInRect(animationPath, &t, rect);
    

    Essentially, this chains three transformations: First, the circle is moved to the origin (0,0), then the rotation is applied and afterwards it is moved back to its original position. I've made a little visualization to illustrate the effect:

    I chose a square instead of a circle and 45° instead of 90° to make the rotation easier to see, but the principle is the same.