Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom circular transition between two views

I want to create an animation similar to the animation for changing inbetween different views in the Spy Mouse app. See this video for reference:

http://www.youtube.com/watch?v=ylFdl7W3Srw

screenshot of the circular animation

I am unable to do the same. My animation shows a rectangular region instead of a circular view.

CABasicAnimation *cornerRadiusAction = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];    

cornerRadiusAction.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
cornerRadiusAction.duration = 5.0f;
cornerRadiusAction.toValue = [NSNumber numberWithFloat:self.view.bounds.size.height*2];
[self.view.layer addAnimation:cornerRadiusAction forKey:nil];
like image 567
Alfa Avatar asked Dec 12 '22 04:12

Alfa


1 Answers

Code in action.

enter image description here

Explanation.

You cannot achieve such an effect simply animating the cornerRadius. You need to use masking of the CALayer and animate change of the size of a circular mask. Code below does what you want. The animated GIF shows it in action.

@property (weak, nonatomic) IBOutlet UIView *customView;

- (IBAction)buttonTapped:(id)sender
{
    // Set up the shape of the circle.
    CGFloat maskDiameter = sqrtf(powf(CGRectGetWidth(_customView.bounds), 2)
                                 + powf(CGRectGetHeight(_customView.bounds), 2));

    CAShapeLayer *mask = [CAShapeLayer layer];

    // Make a circular shape.
    mask.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0f,
                                                                   0.0f,
                                                                   maskDiameter,
                                                                   maskDiameter)
                                           cornerRadius:maskDiameter/2.0f].CGPath;
    // Center the shape in the view.
    mask.position = CGPointMake((CGRectGetWidth(_customView.bounds) - maskDiameter)/2,
                                (CGRectGetHeight(_customView.bounds) - maskDiameter)/2);

    // Fill the circle.
    mask.fillColor = [UIColor blackColor].CGColor;

    // Add as a mask to the parent layer
    _customView.layer.mask = mask;

    // Animate.
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
    animation.duration = 5.0f;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;

    // Create new path.
    CGPathRef newPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(maskDiameter/2.0f,
                                                                           maskDiameter/2.0f,
                                                                           0.0f,
                                                                           0.0f)
                                                   cornerRadius:0.0f].CGPath;
    // Set start and end values.
    animation.fromValue = (id)mask.path;
    animation.toValue = (__bridge id)newPath;

    // Start the animaiton.
    [mask addAnimation:animation forKey:@"path"];

}
like image 197
Rafa de King Avatar answered Jan 03 '23 23:01

Rafa de King