1. 程式人生 > 實用技巧 >iOS 圓形水波浪效果實現

iOS 圓形水波浪效果實現

https://www.jianshu.com/p/1c947bb906cb?utm_campaign

水波浪效果如下

waterWave.gif

最近專案中用到一個小的波浪動畫,查閱了一些資料如下:
網上參考的一些效果
CDNS上的原理

主要實現方法

  • 水波動畫的關鍵點就是正餘弦函式
  • 這個效果主要的思路是新增兩條曲線 一條正弦曲線、一條餘弦曲線 然後在曲線下新增深淺不同的背景顏色,從而達到波浪顯示的效果

正弦型函式解析式:y=Asin(ωx+φ)+h
各常數值對函式影象的影響:
φ(初相位):決定波形與X軸位置關係或橫向移動距離(左加右減)
ω:決定週期(最小正週期T=2π/|ω|)
A:決定峰值(即縱向拉伸壓縮的倍數)
h:表示波形在Y軸的位置關係或縱向移動距離(上加下減)

正弦.png

我們想要繪製一條函式,這個曲線其實都是柵格的畫素點組成。可以沿著假想的曲線繪製許多個點,然後把點逐一用直線連在一起,如果點足夠多,就可以得到一條滿足需求的曲線,這也是一種微分的思想。而這些點的位置可以通過正弦函式的解析式求得。
如果要繪製上面這個曲線,可以觀察:波的峰值是1,週期是2π,初相位是0,h位移也是0。那麼計算各個點的座標公式就是y = sin(x);獲得各個點的座標之後,使用CGPathAddLineToPoint這個函式,把這些點逐一連成線,就可以得到最後的路徑。

另外一條波浪使用餘弦函式,同樣的原理,使得2條波浪錯開顯示。

//繪製的部分程式碼
    CGFloat waterWaveWidth = self.bounds.size.width;
    //初始化運動路徑
    CGMutablePathRef path = CGPathCreateMutable();
    
    CGMutablePathRef maskPath = CGPathCreateMutable();
    //設定起始位置
    CGPathMoveToPoint(path, nil, 0, _waveY);
    //設定起始位置
    CGPathMoveToPoint(maskPath, 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);
        
    }

現在 我們有了一條靜態的線,那怎麼讓他動起來呢?

平移後的影象

我們可以讓他向左或者向右平移 每隔一段時間平移一次 使用CADisplayLink 使得平移看起來更加的流暢;

//以螢幕重新整理速度為週期刷新曲線的位置
    _disPlayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(waveAnimation:)];
    [_disPlayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

然後在利用CAShapeLayer繪製該波浪。

至此動畫的基本原理就搞清楚了,具體的程式碼實現在demo地址:)



作者:CoderSJun
連結:https://www.jianshu.com/p/1c947bb906cb
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。