在上一篇研究了動效之後,這段時間一直在琢磨如何做一些更有趣的東西,所以,昨天我開源了一個新的聲波庫——Waver,擁有非常動人的聲波效果,在此要感謝 SCSiriWaveformView 這個項目,Waver 在他的基礎上改成了 Block 的使用方式,同時聲波采用我最熟悉的 UIBezierPath 和 CAShapeLayer 實現,並做了一些邏輯上的優化,實現了 8 倍的性能提升。
采用 UIBezierPath & CAShapeLayer 的另外一個好處是更方便對初始形態進行調整,像 Siri 那樣可以從圓形變成線條。
你也可以下載它的示例視頻。
不過對此而言,怎麼使用不是最重要的,重要的是怎麼實現這樣的效果,So,Lets have some fun!
原理
在大概半年多前的時候,iOS 群裡曾有過關於如何實現像 Siri 的聲波效果的討論,當時提出的第一個解決方案是 FFT ,網易公開課有斯坦福相關的課程。
傅立葉原理:任何連續測量的時序或信號,都可以表示為不同頻率的正弦波信號的無限疊加。
不過解釋或者推導再應用這個原理顯然不那麼有趣,我想從一個純粹的邏輯角度出發去解決這個事情。
Mac 上有個非常有趣的軟件,叫做 Grapher,你可以在裡面輸入我們玩的公式,也可以直接下載我們的試驗文件。
屏幕上的波紋
長按 Home 叫出 Siri,千裡之行的第一步就是在屏幕上畫出一個從左邊緣到右邊緣的周期性線條。
要不就試試三角函數 Sine 呗。
對這個基本函數我們需要以下幾個操作做基本調整
1.函數周期變化的 x 范圍限制
符合手機屏幕的寬度,假設為 32
2.在 x 內變化的周期數限制
假設我們需要 2 個周期變化
3.波峰限制
我們需要峰值不超過我們 UIView 容器的高度,所以假設 UIView 搞是 20,那麼峰值應該限制在 10 以內
4.五個波紋
依次波峰遞減 1/5
波紋的限制
上面已經非常接近我們想要的效果了,但是還有一個比較重要的,就是最終出來的效果應該是越靠近屏幕中間的位置,波峰越大,靠近屏幕邊緣的地方,無限接近於靜止。
那麼我們還需要一個參數(一元二次方程)來調整。
滿足在 x 的范圍內,值從 0 - 正數值 變化
那麼這兩個函數相乘的時候,就能實現我們想要的效果
Animate
如何讓這個動起來呢?
滿足一下兩個條件
1.一個用來調整波峰的參數
把聲音的音量處理後作為參數傳入,於函數相乘。
2.循環進行 x 變化的參數
使用 CADisplayLink 作為循環器,聲明一個位移量,每次循環的時候進行遞增,然後傳入我們的函數。
再續前緣
ThunderSpace HD 是個很不錯的雨聲模擬軟件,在一個個風雨交加的夜晚,我時常分不清真實還是幻境。
(本文作者:@周楷雯Kevin)