開發過程中經常有意無意地刻意避開數學相關的知識,你也知道解數學題非常枯燥無趣。平時寫動畫也儘量使用 css3 來實現,timer-function 隨意選用,最多也就調一下 cubic-bezier,找到看著舒服的就行。但是怎樣讓動畫更順滑,寫出更貼近自然的動畫,說實話以前我沒怎麼考慮過。 每次當動 ...
開發過程中經常有意無意地刻意避開數學相關的知識,你也知道解數學題非常枯燥無趣。平時寫動畫也儘量使用 css3 來實現,timer-function 隨意選用,最多也就調一下 cubic-bezier,找到看著舒服的就行。但是怎樣讓動畫更順滑,寫出更貼近自然的動畫,說實話以前我沒怎麼考慮過。
每次當動效設計師提出,能不能這樣那樣的時候,我會理所當然地予以否決。所以有很長一段時間,我非常羡慕那些能用 canvas 繪製很酷炫的動畫的程式員。
先這樣吧,又不是不會動。
今天來分享一下三角函數相關的內容,如果剛學前端的時候有人教我這些,我會很開心。
三角函數
三角函數已經是老生常談了(街舞圈稱之為 Old School),它伴隨我們從初中到大學,太多的公式定理,光是應付考試就花了不少時間。先簡單回顧一下,確保你還記得基礎知識。
勾股定理
最開始學三角函數的時候就是從背勾三股四弦五開始,勾股定理描述的是對於直角三角形,直角兩條邊的平方和等於斜邊的平方。
常用三角函數
印象中教科書裡面只保留了 sin, cos, tan,其他可以通過變換得到。
sinθ = a / h cosθ = b / h tanθ = a / b
極坐標系和單位圓
在笛卡爾直角坐標系中,任一點 (x, y) 都可以轉化成極坐標表示 (r, θ),其中
r = Math.sqrt(x^2 + y^2) θ = Math.atan2(y, x)
單位圓的定義是半徑為單位長度的圓,圓上任意一點的橫坐標就是對應角度的餘弦值,任意點的縱坐標就是對應角度的正弦值。
單位圓
簡單的圖像變換以正弦曲線為例,對函數進行簡單的變換,得到不一樣的結果。
正弦曲線公式:y = A sin(Bx + C) + D
A 控制振幅,A 值越大,波峰和波谷越大,A 值越小,波峰和波谷越小;B 值會影響周期,B 值越大,那麼周期越短,B 值越小,周期越長。C 值會影響圖像左右移動,C 值為正數,圖像左移,C 值為負數,圖像右移。D 值控制上下移動。
這個公式非常有用,如果下文的代碼讓你不解,記得回來查看註解。
簡單得回顧一下之後,確保你還記得這些基礎知識,那麼這些曾經被得滾瓜爛熟的內容,和前端代碼結合會變成什麼樣?
常見的應用場景
圖像應用
最直觀的應用是使用三角函數來繪製 Wave 曲線
for (let x = 0; x < width; x++) { const y = Math.sin(x * a) * amplitude }
再結合三角函數偏移讓左右成為波谷,中間成為波峰,就能得到曼妙的波紋。
for (let x = 0; x < width; x++) { const radians = x / width * Math.PI * 2 const scale = (Math.sin(radians - Math.PI * 0.5) + 1) * 0.5 const y = Math.sin(x * 0.02 + xSpeed) * amplitude * scale }
之前掘金上很火的一篇文章,也是同樣的道理,使用兩層正弦函數繪製曲線,fill 之後加上 stagger 動畫,就能得到非常酷炫的