在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

您好,歡迎來電子發(fā)燒友網! ,新用戶?[免費注冊]

您的位置:電子發(fā)燒友網>源碼下載>通訊/手機編程>

iOS系統(tǒng)中的pop動畫引擎的使用

大小:0.12 MB 人氣: 2017-09-26 需要積分:1

  

  iOS可以通過CADisplayLink實現(xiàn)自定義動畫引擎,pop就是基于此實現(xiàn)的,而且比原生Core Animation更強大好用。譬如當ViewController側滑返回的時候,系統(tǒng)會將Core Animation的動畫會停止,而基于CADisplayLink實現(xiàn)的動畫則不會停止,因而可以實現(xiàn)類似網易云音樂從播放頁側滑時hold住專輯封面圖旋轉的效果。

  八一八魔性的pop

  1、實用的宏

  #define POP_ARRAY_COUNT(x) sizeof(x) / sizeof(x[0]) #define FB_PROPERTY_GET(stype, property, ctype) \ - (ctype)property { \ return ((stype *)_state)-》property; \ } #define FB_PROPERTY_SET(stype, property, mutator, ctype, 。。.) \ - (void)mutator (ctype)value { \ if (value == ((stype *)_state)-》property) \ return; \ ((stype *)_state)-》property = value; \ __VA_ARGS__ \ } #define FB_PROPERTY_SET_OBJ_COPY(stype, property, mutator, ctype, 。。.) \ - (void)mutator (ctype)value { \ if (value == ((stype *)_state)-》property) \ return; \ ((stype *)_state)-》property = [value copy]; \ __VA_ARGS__ \ }

  2、判定值的數(shù)據(jù)類型

  pop定義了支持的值的數(shù)據(jù)類型

  const POPValueType kPOPAnimatableSupportTypes[10] = {kPOPValueInteger, kPOPValueFloat, kPOPValuePoint, kPOPValueSize, kPOPValueRect, kPOPValueEdgeInsets, kPOPValueColor, kPOPValueSCNVector3, kPOPValueSCNVector4};

  通過@encode指令,將給定類型編碼的內部字符串與objcType對比,得到值的數(shù)據(jù)類型

  static bool FBCompareTypeEncoding(const char *objctype, POPValueType type) { switch (type) { case kPOPValueFloat: return (strcmp(objctype, @encode(float)) == 0 || strcmp(objctype, @encode(double)) == 0 ); case kPOPValuePoint: return (strcmp(objctype, @encode(CGPoint)) == 0 #if !TARGET_OS_IPHONE || strcmp(objctype, @encode(NSPoint)) == 0 #endif ); case kPOPValueSize: return (strcmp(objctype, @encode(CGSize)) == 0 #if !TARGET_OS_IPHONE || strcmp(objctype, @encode(NSSize)) == 0 #endif ); case kPOPValueRect: return (strcmp(objctype, @encode(CGRect)) == 0 #if !TARGET_OS_IPHONE || strcmp(objctype, @encode(NSRect)) == 0 #endif ); case kPOPValueEdgeInsets: #if TARGET_OS_IPHONE return strcmp(objctype, @encode(UIEdgeInsets)) == 0; #else return false; #endif case kPOPValueAffineTransform: return strcmp(objctype, @encode(CGAffineTransform)) == 0; case kPOPValueTransform: return strcmp(objctype, @encode(CATransform3D)) == 0; case kPOPValueRange: return strcmp(objctype, @encode(CFRange)) == 0 || strcmp(objctype, @encode (NSRange)) == 0; case kPOPValueInteger: return (strcmp(objctype, @encode(int)) == 0 || strcmp(objctype, @encode(unsigned int)) == 0 || strcmp(objctype, @encode(short)) == 0 || strcmp(objctype, @encode(unsigned short)) == 0 || strcmp(objctype, @encode(long)) == 0 || strcmp(objctype, @encode(unsigned long)) == 0 || strcmp(objctype, @encode(long long)) == 0 || strcmp(objctype, @encode(unsigned long long)) == 0 ); case kPOPValueSCNVector3: #if SCENEKIT_SDK_AVAILABLE return strcmp(objctype, @encode(SCNVector3)) == 0; #else return false; #endif case kPOPValueSCNVector4: #if SCENEKIT_SDK_AVAILABLE return strcmp(objctype, @encode(SCNVector4)) == 0; #else return false; #endif default: return false; } }

  3、將值的數(shù)據(jù)類型標準化為Vector

  舉個CGRect類型的例子:

  case kPOPValueRect: vec = Vector::new_cg_rect([value CGRectValue]); Vector *Vector::new_cg_rect(const CGRect &r) { Vector *v = new Vector(4); v-》_values[0] = r.origin.x; v-》_values[1] = r.origin.y; v-》_values[2] = r.size.width; v-》_values[3] = r.size.height; return v; }

  通過Vector的兩個參數(shù)size_t _count;、CGFloat *_values;將給定的類型抽象出來,實現(xiàn)解耦。此外還有一個好處,當創(chuàng)建屬性動畫為kPOPLayerBounds,但toValue屬性賦值的是一個NSNumber,得益于_values是數(shù)組指針,并不會引發(fā)數(shù)組越界導致的crash,只是動畫效果不可預期。

  4、基于NSRunLoop的動畫更新機制

  - (void)_scheduleProcessPendingList { // see WebKit for magic numbers, eg http://trac.webkit.org/changeset/166540 static const CFIndex CATransactionCommitRunLoopOrder = 2000000; static const CFIndex POPAnimationApplyRunLoopOrder = CATransactionCommitRunLoopOrder - 1; // lock OSSpinLockLock(&_lock); if (!_pendingListObserver) { __weak POPAnimator *weakSelf = self; _pendingListObserver = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopBeforeWaiting | kCFRunLoopExit, false, POPAnimationApplyRunLoopOrder, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { [weakSelf _processPendingList]; }); if (_pendingListObserver) { CFRunLoopAddObserver(CFRunLoopGetMain(), _pendingListObserver, kCFRunLoopCommonModes); } } // unlock OSSpinLockUnlock(&_lock); }

  在主線程RunLoop中添加觀察者,監(jiān)聽了kCFAllocatorDefault、kCFRunLoopBeforeWaiting、kCFRunLoopExit事件,在收到回調的時候,處理_pendingList里的動畫。

  5、更新動畫的回調數(shù)組

  static POPStaticAnimatablePropertyState _staticStates[] = { /* CALayer */ {kPOPLayerBackgroundColor, ^(CALayer *obj, CGFloat values[]) { POPCGColorGetRGBAComponents(obj.backgroundColor, values); }, ^(CALayer *obj, const CGFloat values[]) { CGColorRef color = POPCGColorRGBACreate(values); [obj setBackgroundColor:color]; CGColorRelease(color); }, kPOPThresholdColor }, {kPOPLayerBounds, ^(CALayer *obj, CGFloat values[]) { values_from_rect(values, [obj bounds]); }, ^(CALayer *obj, const CGFloat values[]) { [obj setBounds:values_to_rect(values)]; }, kPOPThresholdPoint }, 。。.

  封裝不同的動畫行為,實現(xiàn)類似模板模式,只需統(tǒng)一調用,即可更新動畫

  // write value write(obj, currentVec-》data());

  6、動畫插值的動態(tài)實現(xiàn)

  switch (type) { case kPOPAnimationSpring: advanced = advance(time, dt, obj); break; case kPOPAnimationDecay: advanced = advance(time, dt, obj); break; case kPOPAnimationBasic: { advanced = advance(time, dt, obj); computedProgress = true; break; } case kPOPAnimationCustom: { customFinished = [self _advance:obj currentTime:time elapsedTime:dt] ? false : true; advanced = true; break; } default: break; }

  可以看出總共有四種動畫插值的算法,以kPOPAnimationBasic為例:

  bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) { // default timing function if (!timingFunction) { ((POPBasicAnimation *)self).timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; } // solve for normalized time, aka progresss [0, 1] CGFloat p = 1.0f; if (duration 》 0.0f) { // cap local time to duration CFTimeInterval t = MIN(time - startTime, duration) / duration; p = POPTimingFunctionSolve(timingControlPoints, t, SOLVE_EPS(duration)); timeProgress = t; } else { timeProgress = 1.; } // interpolate and advance interpolate(valueType, valueCount, fromVec-》data(), toVec-》data(), currentVec-》data(), p); progress = p; clampCurrentValue(); return true; }

  依照給定的timingFunction,使用POPTimingFunctionSolve計算貝塞爾曲線的變化率,再通過混合計算#define MIX(a, b, f) ((a) + (f) * ((b) - (a))),最終得到動畫的插值。

  小結

  pop中還有很多有意思的地方,譬如TransformationMatrix里的矩陣操作,這里就暫且不挖WebCore底層了。簡而言之,無論性能(c++混編)、易用、容錯,pop都有著作為引擎該有的特性,而它所暴露的和Core Animation相似的接口也讓人極易上手!

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發(fā)表評論

      用戶評論
      評價:好評中評差評

      發(fā)表評論,獲取積分! 請遵守相關規(guī)定!

      ?
      主站蜘蛛池模板: 国产美女作爱 | 九七婷婷狠狠成人免费视频 | 亚洲乱码一区二区三区在线观看 | 四虎最新地址 | 午夜免费成人 | 阿v视频在线观看免费播放 爱爱视频天天干 | 国产xxxxxx久色视频在 | 国内真实实拍伦视频在线观看 | 欧美黑人性xxx猛交 欧美黑人性受xxxx精品 | 久青草国产手机在线观 | 久99频这里只精品23热 视频 | 人人干人人干 | 国产特黄特色的大片观看免费视频 | 毛片基地在线 | 一本大道一卡二卡四卡 | 五月激激| 午夜精品aaa国产福利 | 天天网综合| 国产一区中文字幕 | 高h文男主又粗又狠 | 欧美成人全部免费观看1314色 | 一二三四日本视频社区 | 欲色综合 | 亚洲午夜免费 | 在线视频毛片 | 欧美极品在线视频 | 很黄很黄的网站免费的 | 亚洲狠狠综合久久 | 欧美a欧美| 国产亚洲人成a在线v网站 | 免费日本网站 | 激激婷婷综合五 | 国产gav成人免费播放视频 | 乱高h亲女 | 色视频免费观看高清完整 | 国产免费午夜高清 | 看全色黄大色大片免费久久 | 日本不卡在线一区二区三区视频 | 高清激情小视频在线观看 | 天天综合在线视频 | 欧美精品网|