原文:
http://nachbaur.com/blog/core-animation-part-1
sample下载地址
http://nachbaur.com/wp-content/uploads/2011/01/CALayerAnimTest.zip
共描述了4个动画
1)轨道环绕,比如月球绕地球
源码:
- self.view.backgroundColor
= [UIColor blackColor]; -
- //
Orbit #1 - CALayer
*orbit1 = [CALayer layer]; - orbit1.bounds
= CGRectMake(0, 0, 200, 200); - orbit1.position
= self.view.center; - orbit1.cornerRadius
= 100; - orbit1.borderColor
= [UIColor redColor].CGColor; - orbit1.borderWidth
= 1.5; -
- CALayer
*planet1 = [CALayer layer]; - planet1.bounds
= CGRectMake(0, 0, 20, 20); - planet1.position
= CGPointMake(100, 0); - planet1.cornerRadius
= 10; - planet1.backgroundColor
= [UIColor redColor].CGColor; - [orbit1
addSublayer:planet1]; -
- CABasicAnimation
*anim1 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - anim1.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLi near]; - anim1.fromValue
= [NSNumber numberWithFloat:0]; - anim1.toValue
= [NSNumber numberWithFloat:((360*M_PI)/180)]; - anim1.repeatCount
= HUGE_VALF; - anim1.duration
= 8.0; - [orbit1
addAnimation:anim1 forKey:@"transform"]; -
- [self.view.layer
addSublayer:orbit1]; -
- //
Orbit #2 - CALayer
*orbit2 = [CALayer layer]; - orbit2.bounds
= CGRectMake(0, 0, 120, 120); - orbit2.position
= planet1.position; - orbit2.cornerRadius
= 60; - orbit2.borderColor
= [UIColor blueColor].CGColor; - orbit2.borderWidth
= 1.5; -
- CALayer
*planet2 = [CALayer layer]; - planet2.bounds
= CGRectMake(0, 0, 16, 16); - planet2.position
= CGPointMake(60, 0); - planet2.cornerRadius
= 8; - planet2.backgroundColor
= [UIColor blueColor].CGColor; - [orbit2
addSublayer:planet2]; -
- CABasicAnimation
*anim2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - anim2.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLi near]; - anim2.fromValue
= [NSNumber numberWithFloat:0]; - anim2.toValue
= [NSNumber numberWithFloat:((360*M_PI)/180)]; - anim2.repeatCount
= HUGE_VALF; - anim2.duration
= 4.0; - [orbit2
addAnimation:anim2 forKey:@"transform"]; -
- [orbit1
addSublayer:orbit2]; -
- //
Orbit #3 - CALayer
*orbit3 = [CALayer layer]; - orbit3.bounds
= CGRectMake(0, 0, 72, 72); - orbit3.position
= planet2.position; - orbit3.cornerRadius
= 36; - orbit3.borderColor
= [UIColor grayColor].CGColor; - orbit3.borderWidth
= 1.5; -
- CALayer
*planet3 = [CALayer layer]; - planet3.bounds
= CGRectMake(0, 0, 12, 12); - planet3.position
= CGPointMake(36, 0); - planet3.cornerRadius
= 6; - planet3.backgroundColor
= [UIColor grayColor].CGColor; - [orbit3
addSublayer:planet3]; -
- CABasicAnimation
*anim3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - anim3.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLi near]; - anim3.fromValue
= [NSNumber numberWithFloat:0]; - anim3.toValue
= [NSNumber numberWithFloat:((360*M_PI)/180)]; - anim3.repeatCount
= HUGE_VALF; - anim3.duration
= 2.0; - [orbit3
addAnimation:anim3 forKey:@"transform"]; -
- [orbit2
addSublayer:orbit3];
2。飘动的云
源码
- UIImage
*cloudImage = [UIImage imageNamed:@"cloud.png"]; -
- CALayer
*cloud = [CALayer layer]; - cloud.contents
= (id)cloudImage.CGImage; - cloud.bounds
= CGRectMake(0, 0, cloudImage.size.width, cloudImage.size.height); - cloud.position
= CGPointMake(self.view.bounds.size.width / 2, -
cloudImage.size.height / 2); - [self.view.layer
addSublayer:cloud]; -
- CGPoint
startPt = CGPointMake(self.view.bounds.size.width + cloud.bounds.size.width / 2, -
cloud.position.y); - CGPoint
endPt = CGPointMake(cloud.bounds.size.width / -2, -
cloud.position.y); -
- CABasicAnimation
*anim = [CABasicAnimation animationWithKeyPath:@"position"]; - anim.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLi near]; - anim.fromValue
= [NSValue valueWithCGPoint:startPt]; - anim.toValue
= [NSValue valueWithCGPoint:endPt]; - anim.repeatCount
= HUGE_VALF; - anim.duration
= 8.0; - [cloud
addAnimation:anim forKey:@"position"];
3。点击后放大又缩小的button, 以及点击后飘动的东西,比如删除时,将文件飘到垃圾箱
源码
- -
(void)loadView { -
[super loadView]; -
self.view.backgroundColor = [UIColor whiteColor]; -
-
UIScrollView *scrollView = [[[UIScrollView alloc] initWithFrame:self.view.bounds] autorelease]; -
scrollView.bounces = YES; -
[self.view addSubview:scrollView]; -
-
// Scale out on click -
{ -
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 320, 24)] autorelease]; -
label.text = @"Scale button"; -
label.textAlignment = UITextAlignmentCenter; -
[label sizeToFit]; -
[scrollView addSubview:label]; -
-
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; -
button.center = CGPointMake(220, 30); -
button.tag = ButtonActionsBehaviorTyp eExpand; -
[button setTitle:@"Delete" forState:UIControlStateNormal]; -
[button sizeToFit]; -
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpIns ide]; -
[scrollView addSubview:button]; -
} -
-
// Animated trash delete -
{ -
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 126, 320, 24)] autorelease]; -
label.text = @"Animate image into trash button"; -
label.textAlignment = UITextAlignmentCenter; -
[label sizeToFit]; -
[scrollView addSubview:label]; -
-
UIImageView *icon = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"carmodel.png"]] autorelease]; -
icon.center = CGPointMake(290, 150); -
icon.tag = ButtonActionsBehaviorTyp eAnimateTrash; -
[scrollView addSubview:icon]; -
-
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; -
button.center = CGPointMake(40, 200); -
button.tag = ButtonActionsBehaviorTyp eAnimateTrash; -
[button setTitle:@"Delete Icon" forState:UIControlStateNormal]; -
[button sizeToFit]; -
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpIns ide]; -
[scrollView addSubview:button]; -
[scrollView bringSubviewToFront:icon]; -
} -
-
// Determine the size of all subviews of the scrollview -
CGRect contentSize = CGRectZero; -
for (UIView *subview in scrollView.subviews) { -
contentSize = CGRectUnion(contentSize, subview.frame); -
} -
scrollView.contentSize = contentSize.size; - }
-
- -
(void)buttonClicked:(id)sender { -
UIView *senderView = (UIView*)sender; -
if (![senderView isKindOfClass:[UIView class]]) -
return; -
-
switch (senderView.tag) { -
case ButtonActionsBehaviorTyp eExpand: { -
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"]; -
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEa seInEaseOut]; -
anim.duration = 0.125; -
anim.repeatCount = 1; -
anim.autoreverses = YES; -
anim.removedOnCompletion = YES; -
anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]; -
[senderView.layer addAnimation:anim forKey:nil]; -
-
break; -
} -
-
case ButtonActionsBehaviorTyp eAnimateTrash: { -
UIView *icon = nil; -
for (UIView *theview in senderView.superview.subviews) { -
if (theview.tag != ButtonActionsBehaviorTyp eAnimateTrash) -
continue; -
if ([theview isKindOfClass:[UIImageView class]]) { -
icon = theview; -
break; -
} -
} -
-
if (!icon) -
return; -
-
UIBezierPath *movePath = [UIBezierPath bezierPath]; -
[movePath moveToPoint:icon.center]; -
[movePath addQuadCurveToPoint:senderView.center -
controlPoint:CGPointMake(senderView.center.x, icon.center.y)]; -
-
CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"]; -
moveAnim.path = movePath.CGPath; -
moveAnim.removedOnCompletion = YES; -
-
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"]; -
scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; -
scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]; -
scaleAnim.removedOnCompletion = YES; -
-
CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"alpha"]; -
opacityAnim.fromValue = [NSNumber numberWithFloat:1.0]; -
opacityAnim.toValue = [NSNumber numberWithFloat:0.1]; -
opacityAnim.removedOnCompletion = YES; -
-
CAAnimationGroup *animGroup = [CAAnimationGroup animation]; -
animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, opacityAnim, nil]; -
animGroup.duration = 0.5; -
[icon.layer addAnimation:animGroup forKey:nil]; -
-
break; -
} -
} - }
4。汽车沿着跑道跑
源码:
- #define
degreesToRadians(x) (M_PI * x / 180.0) - #define
P(x,y) CGPointMake(x, y) -
- @implementation
RaceTrackViewController -
- -
(void)loadView { -
[super loadView]; -
-
self.view.backgroundColor = [UIColor greenColor]; -
-
UIBezierPath *trackPath = [UIBezierPath bezierPath]; -
[trackPath moveToPoint:P(160, 25)]; -
[trackPath addCurveToPoint:P(300, 120) -
controlPoint1:P(320, 0) -
controlPoint2:P(300, 80)]; -
[trackPath addCurveToPoint:P(80, 380) -
controlPoint1:P(300, 200) -
controlPoint2:P(200, 480)]; -
[trackPath addCurveToPoint:P(140, 300) -
controlPoint1:P(0, 300) -
controlPoint2:P(200, 220)]; -
[trackPath addCurveToPoint:P(210, 200) -
controlPoint1:P(30, 420) -
controlPoint2:P(280, 300)]; -
[trackPath addCurveToPoint:P(70, 110) -
controlPoint1:P(110, 80) -
controlPoint2:P(110, 80)]; -
[trackPath addCurveToPoint:P(160, 25) -
controlPoint1:P(0, 160) -
controlPoint2:P(0, 40)]; -
-
CAShapeLayer *racetrack = [CAShapeLayer layer]; -
racetrack.path = trackPath.CGPath; -
racetrack.strokeColor = [UIColor blackColor].CGColor; -
racetrack.fillColor = [UIColor clearColor].CGColor; -
racetrack.lineWidth = 30.0; -
[self.view.layer addSublayer:racetrack]; -
-
CAShapeLayer *centerline = [CAShapeLayer layer]; -
centerline.path = trackPath.CGPath; -
centerline.strokeColor = [UIColor whiteColor].CGColor; -
centerline.fillColor = [UIColor clearColor].CGColor; -
centerline.lineWidth = 2.0; -
centerline.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:6], [NSNumber numberWithInt:2], nil]; -
[self.view.layer addSublayer:centerline]; -
-
CALayer *car = [CALayer layer]; -
car.bounds = CGRectMake(0, 0, 44.0, 20.0); -
car.position = P(160, 25); -
car.contents = (id)([UIImage imageNamed:@"carmodel.png"].CGImage); -
[self.view.layer addSublayer:car]; -
-
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"]; -
anim.path = trackPath.CGPath; -
anim.rotationMode = kCAAnimationRotateAuto; -
anim.repeatCount = HUGE_VALF; -
anim.duration = 8.0; -
[car addAnimation:anim forKey:@"race"]; - }