關鍵幀動畫是在動畫控制過程中開發者指定主要的動畫狀態,至于各個狀態間動畫如何進行則由系統自動運算補充(每兩個關鍵幀之間系統形成的動畫稱為“補間動畫”),這種動畫的好處就是開發者不用逐個控制每個動畫幀,而只要關心幾個關鍵幀的狀態即可。
?關鍵幀動畫開發分為兩種形式:一種是通過設置不同的屬性值進行關鍵幀控制,另一種是通過繪制路徑進行關鍵幀控制。后者優先級高于前者,如果設置了路徑則屬性值就不再起作用。
?我們可以通過關鍵幀動畫的values屬性控制動畫的軌跡。假設我們的動畫軌跡是s型的,我們添加幾個關鍵幀就好了,具體如下
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController () <CAAnimationDelegate>
@property (nonatomic, strong) CALayer *animationCALayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.animationCALayer = [[CALayer alloc] init];
self.animationCALayer.bounds = CGRectMake(0, 0, 40, 40);
self.animationCALayer.position = CGPointMake(50, 150);
self.animationCALayer.contents = (id)[UIImage imageNamed:@"vehicleResource.png"].CGImage;
[self.view.layer addSublayer:self.animationCALayer];
[self translationAnimation];
}
#pragma mark - 關鍵幀動畫
- (void) translationAnimation {
// 1、創建關鍵幀動畫并設置動畫屬性
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
// 2、設置關鍵幀,這里有四個關鍵幀
NSValue *key1 = [NSValue valueWithCGPoint:self.animationCALayer.position]; //對于關鍵幀動畫初始值不能省略
NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(160, 200)];
NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(45, 300)];
NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
NSArray *values = @[key1, key2, key3, key4];
keyframeAnimation.values = values;
//設置其他屬性
keyframeAnimation.duration = 4.0;
keyframeAnimation.beginTime = CACurrentMediaTime() + 2;//設置延遲2秒執行
// 4、添加動畫到圖層,添加動畫后就會執行動畫
[self.animationCALayer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
?如果我們想要的路徑是曲線而不是折線,我們可以通過描繪路徑進行關鍵幀動畫控制。
#pragma mark - 關鍵幀動畫
- (void) translationAnimation {
// 1、創建關鍵幀動畫并設置動畫屬性
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// 2、設置路徑
// 繪制貝塞爾曲線
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.animationCALayer.position.x, self.animationCALayer.position.y); // 移動到起始點
CGPathAddCurveToPoint(path, NULL, -50.0, 200.0, 150.0, 300.0,100.0, 500.0); // 繪制二次貝塞爾曲線
keyframeAnimation.path = path; // 設置path屬性
CGPathRelease(path); // 釋放路徑對象
// 設置其他屬性
keyframeAnimation.duration = 6.0;
keyframeAnimation.beginTime = CACurrentMediaTime() + 10; // 設置延遲2秒執行
// 3、添加動畫到圖層,添加動畫后就會執行動畫
[self.animationCALayer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];
}
其他屬性
keyTimes:各個關鍵幀的時間控制。前面使用values設置了四個關鍵幀,默認情況下每兩幀之間的間隔為:4/(4-1)秒。如果想要控制動畫從第一幀到第二針占用時間2秒,從第二幀到第三幀時間為1秒,而從第三幀到第四幀時間1秒的話,就可以通過keyTimes進行設置。keyTimes中存儲的是時間占用比例點,此時可以設置keyTimes的值為0.0,0.5,0.75,1.0(當然必須轉換為NSNumber),也就是說1到2幀運行到總時間的50%,2到3幀運行到總時間的75%,3到4幀運行到4秒結束。
caculationMode:動畫計算模式。還拿上面keyValues動畫舉例,之所以1到2幀能形成連貫性動畫而不是直接從第1幀經過8/3秒到第2幀是因為動畫模式是連續的(值為kCAAnimationLinear,這是計算模式的默認值);而如果指定了動畫模式為kCAAnimationDiscrete離散的那么你會看到動畫從第1幀經過8/3秒直接到第2幀,中間沒有任何過渡。其他動畫模式還有:kCAAnimationPaced(均勻執行,會忽略keyTimes)、kCAAnimationCubic(平滑執行,對于位置變動關鍵幀動畫運行軌跡更平滑)、kCAAnimationCubicPaced(平滑均勻執行)。