【W(wǎng)eb動畫】SVG 線條動畫
通常我們說的 Web 動畫,包含了三大類。
- CSS3 動畫
- javascript 動畫(canvas)
- html 動畫(SVG)
個人認(rèn)為 3 種動畫各有優(yōu)劣,實(shí)際應(yīng)用中根據(jù)掌握情況作出取舍,本文討論的是我認(rèn)為 SVG 中在實(shí)際項目中非常有應(yīng)用價值 SVG 線條動畫。
舉個栗子
SVG 線條動畫,在一些特定的場合下可以解決使用 CSS 無法完成的動畫。尤其是在進(jìn)度條方面,看看最近項目里的一個小需求,一個這種形狀的進(jìn)度條:

把里面的進(jìn)度條單獨(dú)拿出來,也就是需要實(shí)現(xiàn)這樣一個效果:

腦洞大開一下,使用 CSS3 如何實(shí)現(xiàn)這樣一個進(jìn)度條呢。
CSS3 是可以做到的,就是很麻煩。但是如果采用 SVG 的話,迎刃而解。
See the Pen 不規(guī)則進(jìn)度條 by Chokcoco (@Chokcoco) on CodePen.
我們假定你在閱讀本文的時候有了一定的 SVG 基礎(chǔ),上面代碼看看就懂了,好了,本文到此結(jié)束。
好吧,還是稍微解釋下,上面進(jìn)度條的主要 SVG 代碼如下:
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" class="circle-load-rect-svg" width="300" height="200" viewbox="0 0 600 400">
- <polyline points="5 5, 575 5, 575 200, 5 200" class="g-rect-path"/>
- <polyline points="5 5, 575 5, 575 200, 5 200" class="g-rect-fill"/>
- </svg>
SVG 為何
可縮放矢量圖形,即SVG,是W3C XML的分枝語言之一,用于標(biāo)記可縮放的矢量圖形。(摘自MDN[1])
上面代碼中,先談?wù)?svg 標(biāo)簽:
- version:表示 <svg> 的版本,目前只有 1.0,1.1 兩種
- xmlns:http://www.w3.org/2000/svg 固定值
- xmlns:xlink:http://www.w3.org/1999/xlink 固定值
- xml:space:preserve 固定值,上述三個值固定,表示命名空間,當(dāng)數(shù)據(jù)單獨(dú)存在svg文件內(nèi)時,這3個值不能省略
- class:就是我們熟悉的 class
- width | height:定義 svg 畫布的大小
- viewbox:定義了畫布上可以顯示的區(qū)域,當(dāng) viewBox 的大小和 svg 不同時,viewBox 在屏幕上的顯示會縮放至 svg 同等大小(暫時可以不用理解)
有了 svg 標(biāo)簽,我們就可以愉快的在內(nèi)部添加 SVG 圖形了,上面,我在 svg 中定義了兩個 polyline 標(biāo)簽。
SVG 基本形狀
polyline:是SVG的一個基本形狀,用來創(chuàng)建一系列直線連接多個點(diǎn)。
其實(shí),polyline 是一個比較不常用的形狀,比較常用的是path,rect,circle 等。這里我使用 polyline 的原因是需要使用 `stroke-linejoin`[2] 和 `stroke-linecap`[3] 屬性,在線段連接處創(chuàng)建圓滑過渡角。
SVG 中定義了一些基本形狀[4]:

SVG 線條動畫
好,終于到本文的重點(diǎn)了。
上面,我們給兩個 polyline 都設(shè)置了 class,SVG 圖形的一個好處就是部分屬性樣式可以使用 CSS 的方式書寫,更重要的是可以配合 CSS 動畫一起使用。
上面,主要的 CSS 代碼:
- .g-rect-path{
- fill: none;
- stroke-width:10;
- stroke:#d3dce6;
- stroke-linejoin:round;
- stroke-linecap:round;
- }
- .g-rect-fill{
- fill: none;
- stroke-width:10;
- stroke:#ff7700;
- stroke-linejoin:round;
- stroke-linecap:round;
- stroke-dasharray: 0, 1370;
- stroke-dashoffset: 0;
- animation: lineMove 2s ease-out infinite;
- }
- @keyframes lineMove {
- 0%{
- stroke-dasharray: 0, 1350;
- }
- 100%{
- stroke-dasharray: 1350, 1350;
- }
- }
這是什么 CSS?怎么除了 animation 全都不認(rèn)識?
莫慌,其實(shí)很多和 CSS 對比一下非常好理解,只是換了個名字:
- fill:類比 css 中的 background-color,給 svg 圖形填充顏色;
- stroke-width:類比 css 中的 border-width,給 svg 圖形設(shè)定邊框?qū)挾?
- stroke:類比 css 中的 border-color,給 svg 圖形設(shè)定邊框顏色;
- stroke-linejoin | stroke-linecap:上文稍微提到過,設(shè)定線段連接處的樣式[5];
- stroke-dasharray:值是一組數(shù)組,沒數(shù)量上限,每個數(shù)字交替表示劃線與間隔的寬度;
- stroke-dashoffset:則是虛線的偏移量
重點(diǎn)講講能夠?qū)崿F(xiàn)線條動畫的關(guān)鍵屬性 stroke-dasharray 。
上面,填充進(jìn)度條,使用了下面這個動畫 :
- @keyframes lineMove {
- 0%{
- stroke-dasharray: 0, 1350;
- }
- 100%{
- stroke-dasharray: 1350, 1350;
- }
- }
stroke-dasharray: 0, 1350;,表示線框短劃線和缺口的長度分別為 0 和 1350,所以一開始整個圖形都是被缺口占據(jù),所以是在視覺效果上長度為 0。
然后過渡到 stroke-dasharray: 1350, 1350,表示線框短劃線和缺口的長度分別為 1350 和 1350,因為整個圖形的長度就是 1350,所以整個進(jìn)度條會被慢慢填充滿。
掌握了這個技巧后,就可以使用 stroke-dasharray 和 stroke-dashoffset 制作很多不錯的交互場景:
SVG 線條動畫實(shí)現(xiàn)按鈕交互

SVG 線條動畫實(shí)現(xiàn)圓形進(jìn)度條

各類按鈕效果

多 SVG 圖形線條動畫配合
之前我司一個 h5 里面應(yīng)用過的,多SVG 圖形線條動畫配合,可以制作一些比較酷炫的動畫,很有科技感。

本文到此結(jié)束,我在我的 Github 上,使用 SVG 實(shí)現(xiàn)了一些圖形 -- SVG奇思妙想[6],Demo可以戳這里[7]。
下篇文章將會詳述非規(guī)則圖形,如何使用 PS + AI 生成 path 路徑,實(shí)現(xiàn) SVG 動畫,放個 Demo,敬請期待。

參考資料
[1]MDN:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial
[2]stroke-linejoin:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-linejoin
[3]stroke-linecap:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-linecap
[4]基本形狀:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Basic_Shapes
[5]設(shè)定線段連接處的樣式:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-linejoin
[6]SVG奇思妙想:
https://github.com/chokcoco/SVG
[7]Demo可以戳這里:
http://sbco.cc/demo/svg/html/index.html