最近Github有一個上很火的開源動畫集叫Animations。
我也很喜歡做動畫動效,特來學習觀摩。因為動效的特殊性,很多情況下這個項目里的動效不能直接Copy到我們現有的項目中直接使用,所以搞清楚她們的實現原理就很有必要了。建議配合源碼學習。
POP按鈕動畫
沒用過的POP的請移步Facebook Pop 使用指南
效果如下
思路 整體效果是用三個CAShapeLayer和一個UILabel組合實現的。CAShapeLayer負責繪制兩個圓的邊和一個實心圓。動畫用POP的POPBasicAnimation
和POPSpringAnimation
。
你的肉眼能看出哪里用得哪種動畫么?實心圓的尺寸變化、和空心圓的繪制進度是POPBasicAnimation
實現的,基本是一個線性動畫,勻速。實心圓的顏色改變用的是POPSpringAnimation
彈簧動畫。
關于CAShapeLayer
CAShapeLayer
是一中特殊的CALayer用于繪制圖形,可以理解成是CoreGraphic的一種對象化封裝。一個CAShapeLayer可以繪制一個簡單圖形。例如例子里的圓
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.lineWidth + self.radius, self.lineWidth + self.radius)
radius:self.radius + self.lineWidth / 2.f
startAngle:self.startAngle
endAngle:self.endAngle
clockwise:self.clockWise];
shapeLayer.path = path.CGPath;
bezierPathWithArcCenter
這個方法中傳入一系列參數,繪制了一條貝塞爾(bezier)曲線,參數分別是中心點、半徑、開始角度、終止角度,是否閉環。
POP文字動畫
POP實現的文字動畫,例子里用的同樣是POPBasicAnimation
,所以也是線性變化的。
- (void)pop_animationDidApply:(POPAnimation *)anim {
NSLog(@"pop_animationDidApply %@", anim);
NSValue *toValue = (NSValue *)[anim valueForKeyPath:@"currentValue"];
CGSize size = [toValue CGSizeValue];
[CATransaction setDisableActions:YES];
CGFloat percent = (size.height - _math.b) / _math.k;
_circleShape1.strokeEnd = percent;
_circleShape2.strokeEnd = percent;
[CATransaction setDisableActions:NO];
UIColor *color = [UIColor colorWithRed:percent green:percent blue:percent alpha:1.f];
double showValue = fabs(percent * 100);
self.label.text = [NSString stringWithFormat:@"%.f%%", showValue];
self.label.textColor = color;
_blurImageView.alpha = 1 - percent;
}
解釋,這個POP動畫的分幀回調,回調中用
NSValue *toValue = (NSValue *)[anim valueForKeyPath:@"currentValue"];
取得當前動畫的值,這個動畫實際只是改變了實心圓的尺寸。然后開發者通過當前尺寸計算出動畫的進度
CGFloat percent = (size.height - _math.b) / _math.k;
CATransaction
動畫開關,禁用了兩個外邊圓的strokeEnd
隱式動畫。
[CATransaction setDisableActions:YES];
如果你不明白CALayer的顯式動畫和隱式動畫的區別,請仿照CALayer的隱式動畫和顯式動畫寫一個Demo對比一下。有更多問題可以在下面留言。
響應鏈
Target模式,很容易理解。
// 按住按鈕后沒有松手的動畫
[_button addTarget:self action:@selector(scaleToSmall) forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];
// 按住按鈕松手后的動畫
[_button addTarget:self action:@selector(scaleAnimations) forControlEvents:UIControlEventTouchUpInside];
// 按住按鈕后拖拽出去的動畫
[_button addTarget:self action:@selector(scaleToDefault) forControlEvents:UIControlEventTouchDragExit];
高斯模糊
高斯模糊(blur)的實現有很多方式,這個源碼里使用的UIImage+ImageEffects
是一個 UIImage
的擴展。
動畫效果通過用blur層覆蓋在普通層上,通過修改blur層alpha值實現。