percent(完成比例),speed(水波紋橫向移動的速度),peak(峰值),period(周期數)
1.實現原理:兩個視圖:MWWaveCycleAnimationView,MWWaveProgressView
MWWaveCycleAnimationView:背景層,如果有外需要外框動畫,這需要添加一層layer進行path動畫
//為外圍圖片添加遮蓋層
- (void)addMaskLayerOnCycleImage {
CGSize size = self.frame.size;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.width * 0.5, size.height * 0.5) radius:size.width * 0.5 - mCYCLEANIMATION_MARGIN * 0.5 startAngle:3 * M_PI_2 endAngle:-M_PI_2 clockwise:NO];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillColor = [UIColor clearColor].CGColor;
maskLayer.strokeColor = [UIColor whiteColor].CGColor;
maskLayer.path = maskPath.CGPath;
maskLayer.lineWidth = mCYCLEANIMATION_MARGIN + 1;
[self.layer addSublayer:maskLayer];
_maskLayer = maskLayer;
// 為遮蓋層添加動畫效果
[self addBaseAnimationWithLayer:maskLayer];
}
// 遮蓋層動畫效果
- (void)addBaseAnimationWithLayer:(CAShapeLayer *)maskLayer {
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
anim.fromValue = @1;
anim.toValue = @0;
anim.duration = mMASKLAYER_DURATION;
anim.repeatCount =2;
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
[maskLayer addAnimation:anim forKey:@"MaskLayerAnimation"];
}
MWWaveProgressView:實現水波效果,正余弦函數計算path,添加layer,并在layer添加動畫,動畫的過程,就是path路徑,調用strokeEnd。
#pragma mark **** 定時器事件
- (void)displayLinkAction {
_offSet -= _speed;
[self percentChange];
// 正弦曲線
CGMutablePathRef sinPath = [self pathWithCurveType:mCurveTypeSin];
_firstWaveLayer.path = sinPath;
CGPathRelease(sinPath);
// 余弦曲線
CGMutablePathRef cosPath = [self pathWithCurveType:mCurveTypeCos];
_secondWaveLayer.path = cosPath;
CGPathRelease(cosPath);
}
#pragma mark **** 通過曲線類型獲得對應的曲線路徑
- (CGMutablePathRef)pathWithCurveType:(mCurveType)curveType {
_waveHeight = (1 - _changePercent) * _height;
CGMutablePathRef mutablePath = CGPathCreateMutable();
CGPathMoveToPoint(mutablePath, nil, 0, _waveHeight);
CGFloat y;
for (CGFloat x = 0.0f; x < _width; x++) {
switch (curveType) {
case 0:
y = _peak * sin(_period * M_PI / _width * x + _offSet) + _waveHeight;
break;
case 1:
y = _peak * cos(_period * M_PI / _width * x + _offSet) + _waveHeight;
break;
default:
break;
}
CGPathAddLineToPoint(mutablePath, nil, x, y);
}
CGPathAddLineToPoint(mutablePath, nil, _width, _height);
CGPathAddLineToPoint(mutablePath, nil, 0, _height);
CGPathCloseSubpath(mutablePath);
return mutablePath;
}
效果圖: