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;
}
效果图: