我们知道,正弦曲线公式可表示为y=Asin(ωx+φ)+k。
A,振幅,最高和最低的距离
ω,角速度,用于控制周期大小,单位x中的起伏个数
k,偏距,曲线整体上下偏移量
φ,初相,左右移动的值
对x轴取点遍历 将y=Asin(ωx+φ)+k,得到的点坐标(x,y)添加 CGPathAddLineToPoint(path1, nil, x, y);就可以得到一条静态曲线。x轴方向运动动态曲线可以表示为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;//宽度内设置一个周期波形
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
运行波形图如下:
如果想要实现类似波浪的波动,可以将曲线下方区域填充
CGPathAddLineToPoint(path1,nil, waveWidth,self.frame.size.height*3/4);
CGPathAddLineToPoint(path1,nil,0,self.frame.size.height*3/4);
运行: