運行效果
波浪效果圖
實現思路
定義一個View,并增加圓形或者自定義背景視圖
畫出靜態正弦函數
遮罩,mask層
定時器,不斷的改變路徑上的各個點,讓波浪動起來
難點
三角函數:假設y = Asin(ωx+φ)+ C
A 表示振幅,也就是使用這個變量來調整波浪的最大的高度
ω 與周期相關,周期 T = 2 x pi / ω 即這個變量用來調整同寬度內顯示的波浪的數量
φ 表示波浪橫向的偏移,也就是使用這個變量來調整波浪的流動
C 表示波浪縱向偏移的位置。
如果你的三角函數還給了敬愛的老師,我在網上大概找了一下比較詳細的教程可以參考下:
正弦函數伸縮變換
三角函數平移變換和周期變換
明白以上算法后,接下來 very easy ! 直接上代碼。
1.畫出靜態三角函數
-?(void)drawWaterWave{
CGMutablePathRef?path?=?CGPathCreateMutable();
CGPathMoveToPoint(path,?NULL,0,?VIEW_HEIGHT/2.0);
for(inti?=0;?i?<=?VIEW_WIDTH?;?i++)?{
CGFloat?y?=?kWaveYMax?*?sin(kWaveDuration*i+self.waveOffset)?+?kWaveYOffset;
CGPathAddLineToPoint(path,?NULL,?i,?y);
}
CGPathAddLineToPoint(path,?NULL,VIEW_WIDTH,?VIEW_HEIGHT);
CGPathAddLineToPoint(path,?NULL,0,?VIEW_HEIGHT);
CGPathCloseSubpath(path);
self.waveLayer.path?=?path;
CGPathRelease(path);
}
2.定時器改變正弦的參數計算出新的位移,然后繪制
-?(void)changeWave{
self.waveOffset?+=?kWaveMoveSpeed;
[self?setNeedsDisplay];
}
-?(CADisplayLink?*)displayLink{
if(_displayLink?==?nil)?{
CADisplayLink?*?displayLink?=?[CADisplayLink?displayLinkWithTarget:self?selector:@selector(changeWave)];
[displayLink?addToRunLoop:[NSRunLoop?currentRunLoop]?forMode:NSRunLoopCommonModes];
_displayLink?=?displayLink;
}
return_displayLink;
}
3.添加背景,并且為上述繪制的波浪添加遮罩
-?(CAShapeLayer?*)circleShapeLayer{
if(_circleShapeLayer?==?nil)?{
CAShapeLayer?*?cirShapeLayer?=?[CAShapeLayer?layer];
[self.layer?addSublayer:cirShapeLayer];
UIBezierPath?*bPath?=?[UIBezierPath?bezierPathWithArcCenter:CGPointMake(VIEW_WIDTH/2.0,?VIEW_HEIGHT/2.0)?radius:VIEW_WIDTH/2.0-?kWaveMargin?startAngle:0endAngle:2*M_PI?clockwise:YES];
cirShapeLayer.path?=?bPath.CGPath;
_circleShapeLayer?=?cirShapeLayer;
}
return_circleShapeLayer;
}
-?(CAShapeLayer?*)waveLayer{
if(_waveLayer?==?nil)?{
CAShapeLayer?*?shapeLayer?=?[CAShapeLayer?layer];
shapeLayer.fillColor?=?[UIColor?grayColor].CGColor;
shapeLayer.lineWidth?=2.0f;
shapeLayer.strokeColor?=?[UIColor?redColor].CGColor;
[self.layer?addSublayer:shapeLayer];
shapeLayer.mask?=?self.circleShapeLayer;
_waveLayer?=?shapeLayer;
}
return_waveLayer;
}
-(CAShapeLayer?*)backShapeLayer{
if(_backShapeLayer?==?nil)?{
UIBezierPath?*bPath?=?[UIBezierPath?bezierPathWithArcCenter:CGPointMake(VIEW_WIDTH/2.0,?VIEW_HEIGHT/2.0)?radius:VIEW_WIDTH/2.0-?kWaveMargin?startAngle:0endAngle:2*M_PI?clockwise:YES];
CAShapeLayer?*?backShapeLayer?=?[CAShapeLayer?layer];
backShapeLayer.path?=?bPath.CGPath;
backShapeLayer.lineWidth?=3.0f;
backShapeLayer.fillColor?=?[UIColor?clearColor].CGColor;
backShapeLayer.strokeColor?=?[UIColor?blueColor].CGColor;
[self.layer?addSublayer:backShapeLayer];
_backShapeLayer?=?backShapeLayer;
}
return_backShapeLayer;
}
以上完成后,水波動畫就可以正常運行了,根本停不下來!