iOS faceBook pop動(dòng)畫(huà)使用

POP是一個(gè)來(lái)自于Facebook,在iOS與OSX上通用的極具擴(kuò)展性的動(dòng)畫(huà)引擎。它在基本的靜態(tài)動(dòng)畫(huà)的基礎(chǔ)上增加的彈簧動(dòng)畫(huà)與衰減動(dòng)畫(huà),使之能創(chuàng)造出更真實(shí)更具物理性的交互動(dòng)畫(huà)。 Pop Animation在使用上和Core Animation很相似,都涉及Animation對(duì)象以及Animation的載體的概念 不同的是Core Animation的載體只能是CALayer,而Pop Animation可以是任意基于NSObject的對(duì)象
POP 使用 Objective-C++ 編寫(xiě),Objective-C++ 是對(duì) C++ 的擴(kuò)展

POP背后的開(kāi)發(fā)者是 Kimon Tsinteris, Push Pop Press 的聯(lián)合創(chuàng)始人,曾經(jīng)在Apple擔(dān)任高級(jí)工程師,并參與了 iPhone 和 iPad 上軟件的研發(fā)(iPhone的指南針以及地圖)。2011年的時(shí)候 Facebook 收購(gòu)了他的公司,此后他便加入了 Facebook 負(fù)責(zé) Facebook iOS 版本的開(kāi)發(fā)。

一.pop的介紹

pop結(jié)構(gòu)圖.png
  • POP 動(dòng)畫(huà)極為流暢,主要在于Enimator 里,POP 通過(guò) CADisplayLink 高達(dá) 60 FPS 的特性,打造了一個(gè)游戲級(jí)的動(dòng)畫(huà)引擎。
  • CADisplayLink 是類(lèi)似 NSTimer 的定時(shí)器,不同之處在于,NSTimer 用于我們定義任務(wù)的執(zhí)行周期、資料的更新周期,他的執(zhí)行受到 CPU 的阻塞影響,而 CADisplayLink 則用于定義畫(huà)面的重繪、動(dòng)畫(huà)的演變,他的執(zhí)行基于 frames 的間隔。
  • 通過(guò) CADisplayLink,Apple 允許你將 App 的重繪速度設(shè)定到和屏幕刷新頻率一致,由此你可以獲得非常流暢的交互動(dòng)畫(huà),這項(xiàng)技術(shù)的應(yīng)用在游戲中非常常見(jiàn),著名的 Cocos-2D 也應(yīng)用了這個(gè)重要的技術(shù)。
  • WebCore 里包含了一些從 Apple 的開(kāi)源的網(wǎng)頁(yè)渲染引擎里拿出的源文件,與 Utility 里的組件一并,提供了 POP 的各項(xiàng)復(fù)雜計(jì)算的基本支持

二.pop動(dòng)畫(huà)

  • POPBasicAnimation //基礎(chǔ)動(dòng)畫(huà)
  • POPSpringAnimation //彈簧動(dòng)畫(huà)
  • POPDecayAnimation //衰減動(dòng)畫(huà)
  • POPCustomAnimation //自定義動(dòng)畫(huà)

POP動(dòng)畫(huà)大部分屬性和CoreAnimation(核心動(dòng)畫(huà))的含義和用法一樣,也有部分特殊屬性
CALayer層各屬性

extern NSString * const kPOPLayerBackgroundColor;//背景色
extern NSString * const kPOPLayerBounds;//bounds
extern NSString * const kPOPLayerCornerRadius;//圓角半徑
extern NSString * const kPOPLayerBorderWidth;
extern NSString * const kPOPLayerBorderColor;
extern NSString * const kPOPLayerOpacity;
extern NSString * const kPOPLayerPosition;
extern NSString * const kPOPLayerPositionX;
extern NSString * const kPOPLayerPositionY;
extern NSString * const kPOPLayerRotation;
extern NSString * const kPOPLayerRotationX;
extern NSString * const kPOPLayerRotationY;
extern NSString * const kPOPLayerScaleX;
extern NSString * const kPOPLayerScaleXY;
extern NSString * const kPOPLayerScaleY;
extern NSString * const kPOPLayerSize;
extern NSString * const kPOPLayerSubscaleXY;
extern NSString * const kPOPLayerSubtranslationX;
extern NSString * const kPOPLayerSubtranslationXY;
extern NSString * const kPOPLayerSubtranslationY;
extern NSString * const kPOPLayerSubtranslationZ;
extern NSString * const kPOPLayerTranslationX;
extern NSString * const kPOPLayerTranslationXY;
extern NSString * const kPOPLayerTranslationY;
extern NSString * const kPOPLayerTranslationZ;
extern NSString * const kPOPLayerZPosition;
extern NSString * const kPOPLayerShadowColor;
extern NSString * const kPOPLayerShadowOffset;
extern NSString * const kPOPLayerShadowOpacity;
extern NSString * const kPOPLayerShadowRadius;

UIVIew層各屬性

extern NSString * const kPOPViewAlpha;
extern NSString * const kPOPViewBackgroundColor;
extern NSString * const kPOPViewBounds;
extern NSString * const kPOPViewCenter;
extern NSString * const kPOPViewFrame;
extern NSString * const kPOPViewScaleX;
extern NSString * const kPOPViewScaleXY;
extern NSString * const kPOPViewScaleY;
extern NSString * const kPOPViewSize;
extern NSString * const kPOPViewTintColor;

其他層視圖層屬性

extern NSString * const kPOPNavigationBarBarTintColor;
extern NSString * const kPOPToolbarBarTintColor;
extern NSString * const kPOPTabBarBarTintColor;
extern NSString * const kPOPLabelTextColor;
  • 更多控件屬性可以參考框架里面類(lèi) POPAnimatableProperty.h

1.POPBasicAnimation基礎(chǔ)動(dòng)畫(huà)

POPBasicAnimation *basic = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionX];
 basic.toValue = @(300);
 basic.duration = 0.33;
 [self.markView pop_addAnimation:basic forKey: kPOPLayerPositionX];

添加一個(gè)動(dòng)畫(huà)最少僅需三步
1)定義一個(gè)animation對(duì)象,并指定對(duì)應(yīng)的動(dòng)畫(huà)屬性(kPOPLayerPositionX)
2)設(shè)置初始值結(jié)束值(初始值可以不指定,會(huì)默認(rèn)從當(dāng)前值開(kāi)始)
3)添加到想產(chǎn)生動(dòng)畫(huà)的對(duì)象上

注意:由于 POP 是基于定時(shí)器定時(shí)刷新添加動(dòng)畫(huà)的原理,那么如果將動(dòng)畫(huà)庫(kù)運(yùn)行在主線程上,會(huì)由于線程阻塞的問(wèn)題導(dǎo)致動(dòng)畫(huà)效果出現(xiàn)卡頓、不流暢的情況。

更為關(guān)鍵的是,你不能將動(dòng)畫(huà)效果放在子線程,因?yàn)槟悴荒軐?duì) view 和 layer 的操作放到主線程之外.POP 受主線程阻塞的影響很大,在使用過(guò)程中,應(yīng)避免在有可能發(fā)生主線程阻塞的情況下使用 POP ,避免制作卡頓的動(dòng)畫(huà)效果,產(chǎn)生不好的用戶體驗(yàn)

2.POPSpringAnimation彈性動(dòng)畫(huà)

屬性介紹

velocity: 設(shè)置動(dòng)畫(huà)開(kāi)始速度
springBounciness: 反彈振幅, 可以設(shè)置的范圍是0-20,默認(rèn)為4。值越大振動(dòng)的幅度越大
springSpeed: 速度, 可以設(shè)置的范圍是0-20,默認(rèn)為12.值越大速度越快,結(jié)束的越快
dynamicsMass: 質(zhì)量, 質(zhì)量越大,動(dòng)畫(huà)的速度越慢,振動(dòng)的幅度越大,結(jié)束的越慢
dynamicsTension: 拉力 拉力越大,動(dòng)畫(huà)的速度越快,結(jié)束的越快
dynamicsFriction: 摩擦力, 摩擦力越大,動(dòng)畫(huà)的速度越慢,振動(dòng)的幅度越小。

注意: 以上的六個(gè)屬性中一般只會(huì)設(shè)置springBounciness和springSpeed, 如有特殊需求才會(huì)設(shè)置其他屬性

 POPSpringAnimation *psa = [POPSpringAnimation animationWithPropertyNamed:kPOPViewScaleX];
  psa.fromValue = @(0.3);
   psa.toValue = @(2);
    psa.springSpeed = 5;
    psa.springBounciness = 15;
    [self.markView pop_addAnimation:psa forKey: kPOPViewScaleX];

3.POPDecayAnimation衰減動(dòng)畫(huà)

可以實(shí)現(xiàn)類(lèi)似UIScrollView的滑動(dòng)衰減效果
屬性介紹

  • deceleration (負(fù)加速度, 衰減系數(shù)(越小則衰減得越快)) 是一個(gè)你會(huì)很少用到的值,默認(rèn)是就是我們地球的 0.998,如果你開(kāi)發(fā)APP給火星人用,那么這個(gè)值你使用 0.376 會(huì)更合適
  • velocity 也是必須和你操作的屬性有相同的結(jié)構(gòu),如果你操作的是 bounds, 傳CGRect類(lèi)型;如果 velocity 是負(fù)值,那么就會(huì)反向遞減
POPDecayAnimation *pda = [POPDecayAnimation animationWithPropertyNamed:kPOPViewSize];
  pda.velocity = [NSValue valueWithCGSize:CGSizeMake(300, self.markView.frame.size.height)];
  [self.markView pop_addAnimation:pda forKey:kPOPViewSize];

4. POPCustomAnimation自定義動(dòng)畫(huà)

請(qǐng)三種動(dòng)畫(huà)是默認(rèn)動(dòng)畫(huà),集成POPPropertyAnimation類(lèi),基類(lèi)中有一個(gè)屬性property 是用來(lái)驅(qū)動(dòng)動(dòng)畫(huà)的。
property包含三個(gè)部分

  • readBlock告訴POP當(dāng)前的屬性值
  • writeBlock中修改變化后的屬性值
  • threashold決定了動(dòng)畫(huà)變化間隔的閾值 值越大writeBlock的調(diào)用次數(shù)越少

前三種動(dòng)畫(huà)POP會(huì)自動(dòng)創(chuàng)建,告訴系統(tǒng)如何根據(jù)當(dāng)前時(shí)間片做出變化

 POPBasicAnimation *anim = [POPBasicAnimation animation];
    anim.duration = 10.0;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    POPAnimatableProperty * prop = [POPAnimatableProperty propertyWithName:@"count" initializer:^(POPMutableAnimatableProperty *prop) {
        prop.readBlock = ^(id obj, CGFloat values[]) {    
          values[0] = [[obj description] floatValue];
       };
        prop.writeBlock = ^(id obj, const CGFloat values[]) {    
            [obj setText:[NSString stringWithFormat:@"%.2f",values[0]]];
        };
      prop.threshold = 0.01;}];
    anim.property = prop;
    anim.fromValue = @(0.0);
    anim.toValue = @(100.0);
    [self.label pop_addAnimation:anim forKey:nil];

kCAMediaTimingFunctionLinear //線性步調(diào)對(duì)于那些立即加速并且保持勻速到達(dá)終點(diǎn)的場(chǎng)景會(huì)有意義
kCAMediaTimingFunctionEaseIn //慢慢加速然后突然停止
kCAMediaTimingFunctionEaseOut //全速開(kāi)始,然后慢慢減速停止
kCAMediaTimingFunctionEaseInEaseOut//慢慢加速然后再慢慢減速
kCAMediaTimingFunctionDefault//同上,加速和減速的過(guò)程都稍微有些慢

三.pop動(dòng)畫(huà)相關(guān)Core Animation的優(yōu)點(diǎn)

  • Pop Animation應(yīng)用于CALayer時(shí),在動(dòng)畫(huà)運(yùn)行的任何時(shí)刻,layer和其presentationLayer的相關(guān)屬性值始終保持一致,而Core Animation做不到。
  • Pop Animation可以應(yīng)用任何NSObject的對(duì)象,而Core Aniamtion必須是CALayer。

四.幾個(gè)比較炫酷的效果

見(jiàn)demo->FacebookPopDemo

demo效果

文章和代碼若有不對(duì)地方,歡迎批評(píng)指正。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容