一、顯示效果
二栋艳、工作原理
實現(xiàn)原理主要是通過繪制出一條正弦曲線和一條余弦曲線蔗包,在兩條曲線上下方添加不同的背景色魂挂,讓曲線按照一個方向移動即可模擬出波浪的效果甫题。首先需要了解曲線公式:
正弦曲線公式:y=Asin(ωx+φ)+k
A :振幅,曲線最高位和最低位的距離
ω :角速度,用于控制周期大小,單位x中起伏的個數(shù)
K :偏距,曲線上下偏移量
φ :初相,曲線左右偏移量
曲線圖如下:
如果讓曲線按照X軸以移動速度移動下去就會出現(xiàn)波浪的效果 涂召,按照以下步驟即可坠非,和把大象放冰箱里的步驟差不多。
第一步:添加一條曲線----->第二步:讓曲線沿x軸移動 ----->第三步:在曲線下部分添加填充色
到這里就完成了一層波浪果正,然后再添加第二層即可炎码,如果第一層為余弦曲線,第二層則需添加正弦曲線秋泳,這樣看起來就會有分層的感覺潦闲。
然后稍加潤色可以了,是不是很簡單迫皱。
三歉闰、代碼
#define BackGroundColor [UIColor colorWithRed:96/255.0f green:159/255.0f blue:150/255.0f alpha:1]
#define WaveColor1 [UIColor colorWithRed:136/255.0f green:199/255.0f blue:190/255.0f alpha:1]
#define WaveColor2 [UIColor colorWithRed:28/255.0 green:203/255.0 blue:174/255.0 alpha:1]
#import "XLWave.h"
@interface XLWave ()
{
//前面的波浪
CAShapeLayer *_waveLayer1;
CAShapeLayer *_waveLayer2;
CADisplayLink *_disPlayLink;
/**
曲線的振幅
*/
CGFloat _waveAmplitude;
/**
曲線角速度
*/
CGFloat _wavePalstance;
/**
曲線初相
*/
CGFloat _waveX;
/**
曲線偏距
*/
CGFloat _waveY;
/**
曲線移動速度
*/
CGFloat _waveMoveSpeed;
}
@end
@implementation XLWave
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self buildUI];
[self buildData];
}
return self;
}
//初始化UI
-(void)buildUI
{
//初始化波浪
//底層
_waveLayer1 = [CAShapeLayer layer];
_waveLayer1.fillColor = WaveColor1.CGColor;
_waveLayer1.strokeColor = WaveColor1.CGColor;
[self.layer addSublayer:_waveLayer1];
//上層
_waveLayer2 = [CAShapeLayer layer];
_waveLayer2.fillColor = WaveColor2.CGColor;
_waveLayer2.strokeColor = WaveColor2.CGColor;
[self.layer addSublayer:_waveLayer2];
//畫了個圓
self.layer.cornerRadius = self.bounds.size.width/2.0f;
self.layer.masksToBounds = true;
self.backgroundColor = BackGroundColor;
}
//初始化數(shù)據(jù)
-(void)buildData
{
//振幅
_waveAmplitude = 10;
//角速度
_wavePalstance = M_PI/self.bounds.size.width;
//偏距
_waveY = 0;
//初相
_waveX = 0;
//x軸移動速度
_waveMoveSpeed = _wavePalstance * 10;
//以屏幕刷新速度為周期刷新曲線的位置
_disPlayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateWave:)];
[_disPlayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
/**
保持和屏幕的刷新速度相同,iphone的刷新速度是60Hz,即每秒60次的刷新
*/
-(void)updateWave:(CADisplayLink *)link
{
//更新X
_waveX += _waveMoveSpeed;
[self updateWaveY];
[self updateWave1];
[self updateWave2];
}
//更新偏距的大小 直到達到目標偏距 讓wave有一個勻速增長的效果
-(void)updateWaveY
{
CGFloat targetY = self.bounds.size.height - _progress * self.bounds.size.height;
if (_waveY < targetY) {
_waveY += 2;
}
if (_waveY > targetY ) {
_waveY -= 2;
}
}
//更新第一層曲線
-(void)updateWave1
{
//波浪寬度
CGFloat waterWaveWidth = self.bounds.size.width;
//初始化運動路徑
CGMutablePathRef path = CGPathCreateMutable();
//設置起始位置
CGPathMoveToPoint(path, nil, 0, _waveY);
//初始化波浪其實Y為偏距
CGFloat y = _waveY;
//正弦曲線公式為: y=Asin(ωx+φ)+k;
for (float x = 0.0f; x <= waterWaveWidth ; x++) {
y = _waveAmplitude * cos(_wavePalstance * x + _waveX) + _waveY;
CGPathAddLineToPoint(path, nil, x, y);
}
//填充底部顏色
CGPathAddLineToPoint(path, nil, waterWaveWidth, self.bounds.size.height);
CGPathAddLineToPoint(path, nil, 0, self.bounds.size.height);
CGPathCloseSubpath(path);
_waveLayer1.path = path;
CGPathRelease(path);
}
//更新第二層曲線
-(void)updateWave2
{
//波浪寬度
CGFloat waterWaveWidth = self.bounds.size.width;
//初始化運動路徑
CGMutablePathRef path = CGPathCreateMutable();
//設置起始位置
CGPathMoveToPoint(path, nil, 0, _waveY);
//初始化波浪其實Y為偏距
CGFloat y = _waveY;
//正弦曲線公式為: y=Asin(ωx+φ)+k;
for (float x = 0.0f; x <= waterWaveWidth ; x++) {
y = _waveAmplitude * sin(_wavePalstance * x + _waveX) + _waveY;
CGPathAddLineToPoint(path, nil, x, y);
}
//添加終點路徑、填充底部顏色
CGPathAddLineToPoint(path, nil, waterWaveWidth, self.bounds.size.height);
CGPathAddLineToPoint(path, nil, 0, self.bounds.size.height);
CGPathCloseSubpath(path);
_waveLayer2.path = path;
CGPathRelease(path);
}
//設置需要顯示的進度衫生,y軸的更新會在[updateWaveY]方法中實現(xiàn)
-(void)setProgress:(CGFloat)progress
{
_progress = progress;
}
//停止動畫
-(void)stop
{
if (_disPlayLink) {
[_disPlayLink invalidate];
_disPlayLink = nil;
}
}
//回收內(nèi)存
-(void)dealloc
{
[self stop];
if (_waveLayer1) {
[_waveLayer1 removeFromSuperlayer];
_waveLayer1 = nil;
}
if (_waveLayer2) {
[_waveLayer2 removeFromSuperlayer];
_waveLayer2 = nil;
}
}
本文Demo地址:Github
延伸:仿百度貼吧加載動畫:
下載地址:Github
原文:https://blog.csdn.net/u013282507/article/details/53121556