我們知道,正弦曲線公式可表示為y=Asin(ωx+φ)+k。
?A,振幅,最高和最低的距離
?ω,角速度,用于控制周期大小,單位x中的起伏個數(shù)
?k,偏距,曲線整體上下偏移量
?φ,初相,左右移動的值
對x軸取點遍歷 將y=Asin(ωx+φ)+k,得到的點坐標(biāo)(x,y)添加?CGPathAddLineToPoint(path1, nil, x, y);就可以得到一條靜態(tài)曲線。x軸方向運動動態(tài)曲線可以表示為y=Asin(ω(x+t)+φ)+k;其中
表示移動速度。代碼如下:
@interface PFWave()
@property (nonatomic, strong) CAShapeLayer *waveLayer1;
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) CGFloat waveAmplitude;//振幅
@property (nonatomic, assign) CGFloat wavePalstance;//角速度
@property (nonatomic, assign) CGFloat waveX;//初相
@property (nonatomic, assign) CGFloat waveY;//偏距
@property (nonatomic, assign) CGFloat waveMoveSpeeed;//曲線移動速度
@property (nonatomic, assign) CGFloat positionX;
@end
@implementation PFWave
- (instancetype)initWithFrame:(CGRect)frame
{
? ? if (self = [super initWithFrame:frame]) {
? ? ? ? self.backgroundColor = BackGroundColor;
? ? ? ? [self createUI];
? ? ? ? [self configData];
? ? ? ? [self updateWave];
? ? }
? ? return self;
}
- (void)createUI
{
? ? self.waveLayer1 = [CAShapeLayer layer];
? ? self.waveLayer1.fillColor = WaveColor1.CGColor;
? ? self.waveLayer1.strokeColor = WaveColor1.CGColor;
? ? [self.layer addSublayer:self.waveLayer1];
? ? self.positionX = 0;
}
- (void)configData
{
? ? self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateWave:)];
? ? [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
? ? self.waveAmplitude = self.frame.size.height/2;
? ? self.waveX = 0.f;
? ? self.waveY = self.frame.size.height/2;
? ? self.wavePalstance = 2*M_PI/self.frame.size.width;//寬度內(nèi)設(shè)置一個周期波形
? ? self.waveMoveSpeeed = 1.0;//每個刷新周期移動1.0
}
- (void)updateWave:(CADisplayLink *)displaylink
{
? ? self.positionX-= self.waveMoveSpeeed;
? ? [self updateWave];
}
- (void)updateWave
{
? ? CGFloat waveWidth = self.frame.size.width;
? ? CGMutablePathRef path1 = CGPathCreateMutable();
? ? CGPathMoveToPoint(path1, nil, 0, self.waveY);
? ? for (NSInteger x = 0; x < waveWidth; x++) {
? ? ? ? CGFloat y = self.waveAmplitude*sin(self.wavePalstance*(x+self.positionX) + self.waveX) +self.waveY;
? ? ? ? CGPathAddLineToPoint(path1, nil, x, y);
? ? }
? ? ? ? CGPathCloseSubpath(path1);
? ? self.waveLayer1.path = path1;
? ? CGPathRelease(path1);
}
@end
運行波形圖如下:

如果想要實現(xiàn)類似波浪的波動,可以將曲線下方區(qū)域填充
CGPathAddLineToPoint(path1,nil, waveWidth,self.frame.size.height*3/4);
CGPathAddLineToPoint(path1,nil,0,self.frame.size.height*3/4);
運行:
