Facebook開源動畫庫 POP-POPDecayAnimation運用,animationcss動畫庫
關於POPDecayAnimation的介紹先引用別人寫的一些內容,基本上把它的一些注意點都說明了;
Decay Animation 就是 POP 提供的另外一個非常特別的動畫,他實現了一個衰減的效果。這個動畫有一個重要的參數 velocity(速率),一般並不用於物體的自發動畫,而是與使用者的互動共生。這個和 iOS7 引入的 UIDynamic 非常相似,如果你想實現一些物理效果,這個也是非常不錯的選擇。
Decay 的動畫沒有 toValue 只有 fromValue,然後按照 velocity 來做衰減操作。如果我們想做一個刹車效果,那麼應該是這樣的。
POPDecayAnimation *anim = [POPDecayAnimation animWithPropertyNamed:kPOPLayerPositionX]; anim.velocity = @(100.0); anim.fromValue = @(25.0); //anim.deceleration = 0.998; anim.completionBlock = ^(POPAnimation *anim, BOOL finished) { if (finished) {NSLog(@"Stop!");}};
這個動畫會使得物體從 X 座標的點 25.0 開始按照速率 100點/s 做減速運動。 這裡非常值得一提的是,velocity 也是必須和你操作的屬性有相同的結構,如果你操作的是 bounds,想實現一個水滴滴到案頭的擴散效果,那麼應該是 [NSValue valueWithCGRect:CGRectMake(0, 0,20.0, 20.0)]
如果 velocity 是負值,那麼就會反向遞減。
deceleration (負加速度) 是一個你會很少用到的值,預設是就是我們地球的 0.998,如果你開發給火星人用,那麼這個值你使用 0.376 會更合適。
執行個體1:建立一個POPDecayAnimation動畫 實現X軸運動 減慢速度的效果
//1:初始化第一個視圖塊 if (self.myView==nil) { self.myView=[[UIView alloc]initWithFrame:CGRectMake(0, 80, 30, 30)]; self.myView.backgroundColor=[UIColor redColor]; [self.view addSubview:self.myView]; } //建立一個POPDecayAnimation動畫 實現X軸運動 減慢速度的效果 通過速率來計算啟動並執行距離 沒有toValue屬性 POPDecayAnimation *anSpring = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX]; anSpring.velocity = @(500); //速率 anSpring.beginTime = CACurrentMediaTime() + 1.0f; [anSpring setCompletionBlock:^(POPAnimation *prop, BOOL fint) { if (fint) { NSLog(@"myView=%@",NSStringFromCGRect(self.myView.frame)); } }]; [self.myView pop_addAnimation:anSpring forKey:@"myViewposition”];
列印出來的值為:myView={{247.00485229492188, 80}, {30, 30}},說明X軸當前已經到247左右的;
執行個體2:建立一個POPDecayAnimation動畫 連續不停的轉動
//2:初始化一個視圖塊 if(self.myRotationView==nil) { self.myRotationView=[[UIView alloc]initWithFrame:CGRectMake(20, 130, 30, 30)]; self.myRotationView.backgroundColor=[UIColor redColor]; [self.view addSubview:self.myRotationView]; } //建立一個POPDecayAnimation動畫 連續不停的轉動 [self performAnimation];封裝的方法:-(void)performAnimation{ [self.myRotationView.layer pop_removeAllAnimations]; POPDecayAnimation *anRotaion=[POPDecayAnimation animation]; anRotaion.property=[POPAnimatableProperty propertyWithName:kPOPLayerRotation]; if (self.animated) { anRotaion.velocity = @(-150); }else{ anRotaion.velocity = @(150); anRotaion.fromValue = @(25.0); } self.animated = !self.animated; anRotaion.completionBlock = ^(POPAnimation *anim, BOOL finished) { if (finished) { [self performAnimation]; } }; [self.myRotationView.layer pop_addAnimation:anRotaion forKey:@"myRotationView"];}
注意像常量kPOPLayerRotation它是作用在層上,所以我們在使用時要把它載入到相應視圖的layer上面;
執行個體3:實現一個拖動視圖運行,將拖動結束後它有減速的效果,當點擊視圖時它將停所有的動畫效果;在減速動畫結束後會有一個判斷,當前視圖的位置是否是觸在屏壁,若有則反彈;
#import "DecayViewController.h"#import <POP.h>@interface DecayViewController() <POPAnimationDelegate>@property(nonatomic) UIControl *dragView;- (void)addDragView;- (void)touchDown:(UIControl *)sender;- (void)handlePan:(UIPanGestureRecognizer *)recognizer;@end@implementation DecayViewController- (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self addDragView];}#pragma mark - POPAnimationDelegate- (void)pop_animationDidApply:(POPDecayAnimation *)anim{ //判斷是否觸屏壁 BOOL isDragViewOutsideOfSuperView = !CGRectContainsRect(self.view.frame, self.dragView.frame); if (isDragViewOutsideOfSuperView) { CGPoint currentVelocity = [anim.velocity CGPointValue]; CGPoint velocity = CGPointMake(currentVelocity.x, -currentVelocity.y); POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPosition]; positionAnimation.velocity = [NSValue valueWithCGPoint:velocity]; positionAnimation.toValue = [NSValue valueWithCGPoint:self.view.center]; [self.dragView.layer pop_addAnimation:positionAnimation forKey:@"layerPositionAnimation"]; }}#pragma mark - Private Instance methods- (void)addDragView{ //拖動 UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; self.dragView = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; self.dragView.center = self.view.center; self.dragView.layer.cornerRadius = CGRectGetWidth(self.dragView.bounds)/2; self.dragView.backgroundColor = [UIColor redColor]; [self.dragView addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown]; [self.dragView addGestureRecognizer:recognizer]; [self.view addSubview:self.dragView];}//點擊時將停所有的動畫效果- (void)touchDown:(UIControl *)sender { [sender.layer pop_removeAllAnimations];}- (void)handlePan:(UIPanGestureRecognizer *)recognizer{ CGPoint translation = [recognizer translationInView:self.view]; recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y); [recognizer setTranslation:CGPointMake(0, 0) inView:self.view]; //手勢結束 if(recognizer.state == UIGestureRecognizerStateEnded) { CGPoint velocity = [recognizer velocityInView:self.view]; POPDecayAnimation *positionAnimation = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition]; positionAnimation.delegate = self; positionAnimation.velocity = [NSValue valueWithCGPoint:velocity]; [recognizer.view.layer pop_addAnimation:positionAnimation forKey:@"layerPositionAnimation"]; }}@end
執行個體中還動用到了POPAnimationDelegate
<POPAnimatorDelegate> - (void)pop_animationDidStart:(POPAnimation *)anim;- (void)pop_animationDidStop:(POPAnimation *)anim finished:(BOOL)finished;- (void)pop_animationDidReachToValue:(POPAnimation *)anim;- (void)pop_animationDidApply:(POPAnimation *)anim;