SVG動態繪製不規則圖形

螞蟻金服資料體驗技術發表於2017-10-13

作者簡介 wuyue 螞蟻金服·資料體驗技術團隊

在瀏覽器中,任意的二維平面圖形均可以通過path路徑的形式描述。然後底層api 直接靜態繪製出來。但是如果想動態的繪製路徑,瀏覽器是沒有直接支援方式的。 本文就是解決這個問題, 為瀏覽器補全這個功能,讓靜態的路徑能方便的動態繪製。

最終效果

先看下最終實現的效果吧~

晶片描繪:

SVG動態繪製不規則圖形

人臉掃描:

SVG動態繪製不規則圖形

人工書寫:

SVG動態繪製不規則圖形

效果還是挺酷炫的,實現的整個開發過程就從接需求開始講起吧。

需求

SVG動態繪製不規則圖形
某一天設計同學發過來一些圖片,說希望能動起來,還原真實場景,真的像寫字, 人臉掃描,電路的感覺??

SVG動態繪製不規則圖形

與設計同學討論了n多姿勢:

  • 淡入淡出
  • 粒子效果,碎裂組合
  • 有小變大,花式旋轉,變形
  • ...

但是設計同學堅持自己的姿勢,就是要還原真實場景,就是要掃描!

SVG動態繪製不規則圖形

於是我就只能:

SVG動態繪製不規則圖形

好了不再扯淡了,迴歸正題~

就瀏覽器動態繪製想到了以下兩個方案:

方案一

瀏覽器雖然沒有提供動態繪製的方法,但是svg提供了一個比較重要的屬性stroke,中文稱之為描邊。最開始想的是用stroke-dasharray設定虛線描邊,然後用animation改變stroke-dashoffset來繪製動態的文案。這樣子可以實現動態繪製的效果。但是有以下幾點不足。

  • 每條path都得寫css的動畫來控制。
  • 繪製過程單一,只能用瀏覽器提供的幾個動畫的演算法,沒法自己控制繪製過程
  • 後續再有這樣的需求,前端都需要大量開發

基於上面幾點,放棄了這個方案。

方案二

我們能不能自己控制svg的繪製過程,實現他的動態繪製呢?好像...是可以的!!

分析svg

首先要先分析svg。不規則圖形都是可以通過ps的鋼筆工具摳圖,然後匯出到AI裡面就可以獲取到該圖形的path資訊。 或者直接讓設計同學提供svg格式的圖片。 最終我們可以獲取到該圖形的path資訊, 舉例如下:

svg.png

上圖是我擷取的 人臉的svg 格式,通過分析裡面格式可以看出,有幾個關鍵資訊:

  • 佈局資訊 , viewBox裡面可以認為是原始大小。
  • style 部分是樣式, 來控制線條的粗細,顏色等。
  • 第三個紅框部分是 路徑資訊, 這裡是有固定格式的, 具體可參考這裡https://developer.mozilla.org/en-US/docs/Web/SVG

最終我們可以將上述資訊轉化如下形式的指令,方便後續程式碼解析。

path.png

命令解析

問題明確了,就是拆分path指令。把每條命令都解析出來, 然後依據每條指令算點,按對應樣式描線。具體流程如下:

step.png

解析指令部分的關鍵程式碼如下:

parse.png

思路是窮舉所有的分隔符,然後對每個分隔符,實現解析部分。窮舉的分隔符如下:

order.png

指令繪製

然後就是每條指令的執行部分程式碼:

line.png
C.png

最終對於每條指令,歸結到 是畫直線, 還是畫曲線, 根據對應的曲線方程,算出對應的點, 然後就是動態的把點連起來,不停地畫線段,最終大量的微小線段組合成複雜圖形。 核心程式碼如下:

lineTo.png
draw.png

描點連線做動畫部分:

animate.png

然後就做到了本文開頭的效果了~

總結

對於複雜圖形, 我們先通過各種手段獲取其路徑資訊。然後把路徑資訊分拆為各條微小指令, 針對每條指令,去實現動畫。通過描點連線的形式實現,最終所有的點連城線,大量的線組合起來就動態繪製出了複雜圖形。

而且我們可以將繪製的速度等開放成配置提供給設計同學,再有這樣的需求,設計同學只需要提供擁有路徑的svg圖片。然後自己調整配置就可以了,解放了前端同學的開發量。

感興趣的同學可以關注專欄或者傳送簡歷至'wuyue.lwy####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~

原文連結:github.com/ProtoTeam/b…

相關文章