簡介:
pop動畫引擎是Facebook公司開源的,主要實現(xiàn)了真實物理系的動畫效果(彈簧效果與衰減效果)
1唯咬、pop動畫引擎的動畫效果非常流程,其最主要原因是底層使用了CADisplayLink來刷新畏浆,每秒達到了60幀胆胰,和游戲引擎相當。
2刻获、pop動畫與CALayer動畫的區(qū)別:CALayer動畫是有中間狀態(tài)的蜀涨,在展示過程中實際上有另一layer層在展示動畫,當在執(zhí)行動畫過程中突然移除掉動畫效果,會直接到指定的最終狀態(tài)勉盅,容易引起不流程的體驗佑颇。
pop動畫是沒有中間狀態(tài)的,在執(zhí)行動畫的過程中草娜,如果中途移除掉動畫效果挑胸,那么layer會停留在當前位置。
實現(xiàn)衰減效果:
1)衰減動畫由POPDecayAnimation來實現(xiàn)
2)需要精確計算停止運動瞬間的加速度才能夠用衰減動畫做出真是的效果
目標效果:拖拽一個圓形小球宰闰,停止拖拽的瞬間小球繼續(xù)向前慢慢移動減速停止茬贵。
代碼實現(xiàn):
#pragma mark -創(chuàng)建一個圓形的小球
- (void)createBtn{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.bounds = CGRectMake(0, 0, 100, 100);
btn.center = self.view.center;
btn.layer.cornerRadius = 50;
btn.layer.masksToBounds = YES;
btn.backgroundColor = [UIColor redColor];
//添加到view中
[self.view addSubview:btn];
//為btn添加拖拽手勢
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(btnPanGes:)];
[btn addGestureRecognizer:pan];
}
#pragma mark - 拖拽事件
- (void)btnPanGes:(UIPanGestureRecognizer *)recognizer{
//獲取拖拽的變化量
CGPoint trans = [recognizer translationInView:recognizer.view];
//動態(tài)改變被拖拽的目標的frame值
recognizer.view.center = CGPointMake(trans.x+recognizer.view.center.x, trans.y+recognizer.view.center.y);
//清空偏移量
[recognizer setTranslation:CGPointZero inView:self.view];
//當停止拖拽的那一瞬間計算加速度并添加衰減動畫
if (recognizer.state == UIGestureRecognizerStateEnded) {
//獲取此時的加速度
CGPoint vo = [recognizer velocityInView:self.view];
//創(chuàng)建衰減動畫
POPDecayAnimation *decay = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
decay.velocity = [NSValue valueWithCGPoint:vo];
[recognizer.view.layer pop_addAnimation:decay forKey:nil];
}
}
實現(xiàn)彈簧效果
1)彈簧效果通過POPSpringAnimation來實現(xiàn)
2)可以通過設置彈性系數(shù)和速度來設置效果
實現(xiàn)目標:一個紅色的視圖像彈簧般變大
代碼實現(xiàn):
- (void)createView{
UIView *showView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
showView.backgroundColor = [UIColor redColor];
showView.center = self.view.center;
//添加到主視圖
[self.view addSubview:showView];
//添加彈簧動畫,對bounds屬性做動畫效果
POPSpringAnimation *spring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds];
spring.springBounciness = 20;//設置彈性系數(shù),數(shù)值越大移袍,震動幅度越大
spring.springSpeed = 0;//設置速度解藻,速度越快,動畫效果越快結束
spring.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 300, 300)];
[showView.layer pop_addAnimation:spring forKey:nil];
}
自定義動畫:
POP默認支持的三種動畫都繼承自POPPropertyAnimation中定義了一個叫property的屬性( 之前沒有用到它是因為POP根據(jù)不同的默認動畫屬性幫你生成了默認的property) 而這個property則是用來驅動POP的動畫效果中的重要一環(huán)葡盗。
POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"prop" initializer:^(POPMutableAnimatableProperty *prop) {
prop.readBlock = ^(id obj, CGFloat values[]) {
};
prop.writeBlock = ^(id obj, const CGFloat values[]) {
};
prop.threshold = 0.01;
}];
其組成就是一個readBlock一個writeBlock和一個threashold
readBlock告訴POP當前的屬性值
writeBlock中修改變化后的屬性值
threashold決定了動畫變化間隔的閾值 值越大writeBlock的調用次數(shù)越少
POPAnimatableProperty其實是POP中一個比較重要的東西 像上面提到的POP自帶的動畫屬性 查看源代碼可以看到也只是POP自動幫你設置好了POPAnimatableProperty而已 其作用就是當動畫的某個時間片被觸發(fā)時 告訴系統(tǒng)如何根據(jù)當前時間片做出變化
自定義屬性實現(xiàn)目標:類似秒表的動畫
代碼:
- (void)animatableProp{
UILabel *lab = [[UILabel alloc]init];
lab.frame = CGRectMake(0, 0, 100,50);
lab.font = [UIFont systemFontOfSize:30];
[self.view addSubview:lab];
lab.center = self.view.center;
POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countDown" initializer:^(POPMutableAnimatableProperty *prop) {
prop.writeBlock = ^(id obj,const CGFloat values[]){
UILabel *label = (UILabel*)obj;
label.text = [NSString stringWithFormat:@"%d:%d:%d",(int)values[0]/60,(int)values[0]%60,(int)(values[0]*100)%100];
};
}];
//秒表采用線性事件函數(shù)
POPBasicAnimation *basic = [POPBasicAnimation linearAnimation];
basic.property = prop;//采用自定義屬性
basic.fromValue = @(0);//從0開始
basic.toValue = @(3*60);//180秒
basic.duration = 3*60;//持續(xù)3分鐘
[lab pop_addAnimation:basic forKey:nil];
}