SVG:浪啊,浪來了,大浪來了

如果你問我當我們想在項目里加一個波浪效果的時候我在想什麼?我的迴路大概是這樣的:

  1. 打開我的 鉻 瀏覽器
  2. 進入 代碼筆 網站
  3. 搜索 浪
  4. 多點幾次下一頁,我的老夥計,哦我的天,寫這些波浪人都是怪物嗎
  5. emmm....這個這個!!這個像設計師要求的
  6. 打開鏈接,CV 二連
  7. 去和設計師去確認眼神

我敢保證這絕對錯不了,這年頭誰會花時間給你畫浪啊,我還要去帶娃練盾反呢。什麼?設計師你再說一遍,這裡的浪花可不可以隨機?我隨你d.....


好吧,其實沒有設計師,也沒有這個需求,只是之前在一個卡片列表裡想給每個卡片加個波浪,但是一頁的卡片看上去都一樣的浪未免太過乏味,所以試著寫了個隨機波浪的效果,效果可以看 這個 Demo ,代碼也在裡面了

這篇文章就講一下實現的思路和自己想的一般情況下隨機波浪的原則,文章沒有代碼,沒有代碼


?? 先拆分下這個動畫

可以看到動畫其是三個波浪圖形組成的,每個單獨無限滾動,所以有了第一個點:

?? 無限滾動的實現

這裡真的是無限長的波浪在那裡往左翻滾嗎?不存在的,在一頁有多個這樣的動畫的情況下,除非想卡爆用戶的電腦

其實這裡做的是個視覺效果,一個波浪真正的樣子是這樣的:

可以看到紅色箭頭是波浪滾動的方向,紅框內的波浪就是我們看到的實際有效波浪,為什麼說是實際有效呢,因為當我們的視區(黃色背景的卡片)的最左側接觸到藍框時,波浪位移會立刻被重置成初始狀態

藍框,其實是和最開始出現在視區內的波段是一毛一樣的,所以一次完整的波浪滾動就是紅框滾完,藍框佔領視區,這時候瞬間再跳到紅框伊始,因為兩段波形是一樣的,就不會有跳躍的感覺,就給人一種無限滾動的體驗。

那麼我們要做到更接近無限是否可以呢,答案是一定的,只要不斷增加紅框內的波長就可以,但這是一種性能和視覺的權衡,略過。

無限滾動就這麼簡單,現在來說說


?? 波的圖形的生成

熟悉 sketch 、PS 或者 AI 的應該都對鋼筆(路徑)工具不陌生,製作這樣的波形在這些工具中就是放置錨點,拉錨邊就可以了,那麼對應 SVG 的操作呢?

?? svg 生成波形的基本思路

這裡 svg 的基本操作就不多做介紹了,隨便貼個教程

先來看一張圖:

紅色的點都是波峰,藍色的點都是波谷,每一個波峰-波谷之間的間隔我們暫時稱為區塊,所以生成一段波形的思路就可以是:

  1. 假設我們的總波長是 4000,那麼我們將其分為兩塊,第一部分的 2000 就對應上文的紅框內的波形,注意這裡我們的視區域將是 1000
  2. 這裡 2000 的長度我們再將其分為 4 個區塊,其實也就是三個波峰,兩個波谷,這裡要注意四個區塊的長度不能相差太大,否則會出現斷崖式的波形,也就是不夠平滑:

3. 確定區塊後,就是放置波峰波谷了,也是同樣的道理,相鄰波峰-波谷的高低差不能太大,否則也會爆炸

4. 三個波峰中,第一個和第三個波峰必須一模一樣,用來和後面的藍框銜接

其實到這裡,經過上面四個步驟後其實我們可以得到的是一個這樣子的圖形,折線圖?!

就缺個平滑了好像!平滑靠什麼實現呢?

?? 三次貝塞爾曲線平滑波形

還是一樣,關於貝塞爾曲線的 教程 隆粽的貼一下!這裡我們再再再先看一下 sketch 中的三次貝塞爾曲線的實現

?? 哦!在這停頓:

這裡我們關注四個點,紅色的波峰,藍色的波谷,以及綠色黃色兩個控制點,我們要著重關注的就是他們,在這次隨機波形中,每個相鄰的峰谷間,我們都要確定兩個控制點,關於這兩個點的這裡我總結的規則是:

  1. 兩點(綠、黃)分別平行於峰谷,也就是 Y 坐標綠點等於峰,黃點等於谷,這樣比較簡單
  2. 兩點的 X 坐標在峰谷所夾的那個區塊X 軸中建位置遊走不超過10-20%的位置

這裡聽上去很不形象,但所做都是為了保證曲線的平滑(說句題外話,其實生成隨機波形最大的難點就在於在有限的空間內儘可能的讓曲線更順滑,在圖形上的意義也就是對控制點的把握)

這步完成後,其實你就已經有了一段實際有效的波浪了,然後!還記得這段實際有效的波浪的長度是 2000 嗎?我們再截取前 1000 長度(藍框內波形)拼接到這段波形後面,Ta Daa..... 我們的一個波形就完成了,接下來再隨機兩個出來,層疊在一起,加個位移動畫,在視區里你就來到海邊咯。

最後,emmmm,大家有人看了以後自己會去實現一下隨機波浪嗎?

不存在的 ??


那麼,做這個到底有啥用呢?好像也沒大用,最後就貼個圖吧:


推薦閱讀:

如何製作 svg 格式的 圖標字體?
SVG及SVG路徑動畫
怎樣做一個圓環放大的動畫
SVG 與 HTML5 的 canvas 各有什麼優點,哪個更有前途?
外刊君談中國第三屆CSS大會

TAG:前端開發 | SVG | CSS |