I'm trying to create a very simple keyframe animation, whereby a graphic Rotates from one angle to another, through a given midpoint.
(The purpose is to be able to animate rotation through an OBTUSE angle of arc GREATER THAN 180 DEGREES, rather than having the animation 'cheat' and go the shortest route, i.e., via the opposite , ACUTE smaller angle -- which can happen when there's only one [i.e, destination] keyframe. To go the 'long' way around, I assume I need an extra keyframe midway through, along the desired arc.)
Here's what I've got so far (which does get the graphic to the desired rotation, via the most acute angle):
#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
...
[UIView beginAnimations:nil context:nil];
CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(desiredEndingAngle));
[UIView setAnimationDuration:0.5];
graphic.transform = cgCTM;
[UIView commitAnimations];
As I understand it, I’m not looking for animation along a Path (since that’s for Translation, rather than Rotation) ...
Anyway, any help would be VERY much appreciated! Thanks in advance.
Think I’ve got it.
Here’s code which does (in this example) a full 270 DEGREE rotation (1.5*pi radians), including various parameters that can be customized further:
CALayer *layer = rotatingImage.layer;
CAKeyframeAnimation *animation;
animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 0.5f;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.values = [NSArray arrayWithObjects: // i.e., Rotation values for the 3 keyframes, in RADIANS
[NSNumber numberWithFloat:0.0 * M_PI],
[NSNumber numberWithFloat:0.75 * M_PI],
[NSNumber numberWithFloat:1.5 * M_PI], nil];
animation.keyTimes = [NSArray arrayWithObjects: // Relative timing values for the 3 keyframes
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:.5],
[NSNumber numberWithFloat:1.0], nil];
animation.timingFunctions = [NSArray arrayWithObjects:
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], // from keyframe 1 to keyframe 2
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; // from keyframe 2 to keyframe 3
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[layer addAnimation:animation forKey:nil];
Thanks!
Try this:
UIImageView* rotatingImage = [[UIImageView alloc] init]];
[rotatingImage setImage:[UIImage imageNamed:@"someImage.png"]];
CATransform3D rotationTransform = CATransform3DMakeRotation(1.0f * M_PI, 0, 0, 1.0);
CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
rotationAnimation.duration = 0.25f;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 1;
[rotatingImage.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
CGPathAddQuadCurveToPoint(path, NULL, 100, 100, 100, 615);
CGPathAddQuadCurveToPoint(path, NULL, 100, 615, 900, 615);
CGPathAddQuadCurveToPoint(path, NULL, 900, 615, 900, 100);
CGPathAddQuadCurveToPoint(path, NULL, 900, 100, 100, 80);
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.path = path;
pathAnimation.duration = 10.0;
[someLayer addAnimation:pathAnimation forKey:nil];