本文做者:錢鴻昌(閃火)javascript
和高清png來作個對比css
繼續對比html
一樣高清的質地,矢量圖不畏懼放大,體積小。這裏要說明一點就是,由於 SVG 中保存的是點、線、面的信息,與分辨率和圖形大小無關,只是跟圖像的複雜程度有關,因此圖像文件所佔的存儲空間一般會比 png 小。前端
優化 SEO 和無障礙的利器,由於 SVG 圖像是使用XML(可擴展標記語言【英語:Extensible Markup Language,簡稱:XML】標記指計算機所能理解的信息符號,經過此種標記,計算機之間能夠處理包含各類信息的文章等)來標記構建的,瀏覽器經過繪製每一個點和線來打印它們,而不是用預約義的像素填充某些空間。這確保 SVG 圖像能夠適應不一樣的屏幕大小和分辨率。vue
因爲是在 XML 中定義的,SVG 圖像比 JPG 或 PNG 圖像更靈活,並且咱們可使用 CSS 和 JavaScript 與它們進行交互。SVG 圖像設置能夠包含 CSS 和 JavaScript。在 react、vue 這種數據驅動視圖的框架下,對於 SVG 操做就更加如魚得水了。(下文會跟你們分享一些小的 SVG 動畫在咱們項目中的實踐)java
在運用層面上,SVG 提供了一些圖像編輯效果,好比屏蔽和剪裁、應用過濾器等等。而且SVG 只是文本,所以可使用 GZip 對其進行有效壓縮。react
大多數教程網上都能找到,這裏寫一些我以爲值得說起的點git
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="49" stroke="black" stroke-width="2" fill="red" />
</svg>
複製代碼
這就是咱們從設計手裏拿到的 SVG 源文件,咱們掰開揉碎了說。首先咱們把 SVG 內部代碼所有去掉不看,因而成了這樣github
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
複製代碼
這是99% SVG 都會表現出來的形式和及一些屬性,其中包含 width、height 這兩個視口屬性,viewBox 視圖屬性,xmlns 屬性。咱們一行一行看web
第一行:包含了 XML 聲明,XML 聲明其實和 HTML 文檔的 DTD 聲明是相似的。類比 HTML5 的聲明方式
<!DOCTYPE html>
複製代碼
SVG 的文檔聲明方式(劃重點:通常若是 SVG 運用在 HTML 裏,咱們能夠不寫這樣的文檔聲明,但若是是單獨的 SVG 文件,那就須要寫了,不然瀏覽器可能會不認識)
<?xml version="1.0" standalone="no"?>
複製代碼
咱們看到的 standalone 屬性是在代表該 xml 聲明是不是獨立的,若是不是即 standalone="no",那後面會引入外部的 dtd ,如第二行第三行所示。 version 屬性用於指明 SVG 文檔遵循規範的版本。 它只容許在根元素<svg>
上使用。 它純粹是一個說明,對渲染或處理沒有任何影響。雖然它接受任何數字,可是隻有1.0 和 1.1.這兩個有效的選擇。
第四行:這是 SVG 內容的開始
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
複製代碼
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
複製代碼
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=100 height="100">
<circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" />
</svg>
複製代碼
當前這個 SVG 的畫布大小是 100 * 100 的畫布,咱們畫上一個半徑爲 49 再加 1 個單位的描邊的圓。恰好撐滿沒毛病。所見即所得。那咱們試一下改變 width 和 height。發現
<svg style="background:#007fff" xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="300">
<circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" />
</svg>
複製代碼
咱們能夠看到藍色區域就是咱們定的 width 和 height ,圖形部分依然是那個圓沒有變化。這樣咱們就理解了 width 和 height 的做用。
<svg style="background:#007fff" xmlns="http://www.w3.org/2000/svg" version="1.1" <!-- viewBox定義-->
viewBox="0, 0, 100, 100"
width="300"
height="300" >
<circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" />
</svg>
複製代碼
咱們能夠看到藍色區域大小不變,而咱們的圓卻變得很大,大到撐滿了整個畫布。沒錯,你的想法是對的,所謂 viewBox 這個屬性能夠理解爲咱們微信聊天時的截圖操做。viewBox 屬性的四個參數,前兩個表示截圖起點,後面兩個表示截圖終點,均是以左上角定點爲原點。最後把截圖再拉伸放在 SVG 畫布上,就成了咱們上面看到的 SVG 了。下面咱們再修改一次 viewBox 成 0, 0, 50, 50 幫助理解
<svg style="background:#007fff" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0, 0, 50, 50" width="300" height="300" >
<circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" />
</svg>
複製代碼
因此整個邏輯大概是這樣的
在 SVG 裏,你能夠把 path 當作是最基本的繪製元素,正由於它是最基本的,萬變不離其宗,他能演化出各類複雜的繪製效果。因此 path 是最基本也是最複雜的繪製元素。
咱們知道一個 path 標籤,最重要的屬性是 d 屬性,它是一組指令和參數的集合。在 d 屬性的值裏,咱們能看到一堆很是複雜的指令字符串。
<path d=" M73.8616812,68.8664775 L74.5015359,74.5939423 L68.1746283,71.7969507 C66.2299599,72.4159872 64.1377269,72.7711218 61.9444643,72.7711218 C51.9719158,72.7711218 43.8883163,65.7823167 43.8883163,57.1611168 C43.8883163,48.5399169 51.9719158,41.5511118 61.9444643,41.5511118 C71.9164005,41.5511118 80,48.5399169 80,57.1611168 C80,61.8286883 77.6181486,66.006419 73.8616812,68.8664775" id="Fill-1" fill="#FFFFFF"></path>
複製代碼
其實徹底不用以爲噁心,這裏繼續掰開揉碎了說
指令 | 參數 | 含義 |
---|---|---|
M | x y | 將畫筆移動到點(x,y) |
L | x y | 畫筆從當前的點繪製線段到點(x,y) |
H | x | 畫筆從當前的點繪製水平線段到點(x,y0),y0 表示繪製前畫筆所在 y 軸座標,也就是 y 軸不變 |
V | y | 畫筆從當前的點繪製豎直線段到點(x0,y),x0 表示繪製前畫筆所在 x 軸座標,也就是 x 軸不變 |
A | rx ry x-axis-rotation large-arc-flag sweep-flag x y | 畫筆從當前的點繪製一段圓弧到點(x,y) |
C | x1 y1, x2 y2, x y | 畫筆從當前的點繪製一段三次貝塞爾曲線到點(x,y) |
S | x2 y2, x y | 特殊版本的三次貝塞爾曲線(省略第一個控制點) |
Q | x1 y1, x y | 繪製二次貝塞爾曲線到點(x,y) |
T | x y | 特殊版本的二次貝塞爾曲線(省略控制點) |
Z | 無參數 | 繪製閉合圖形,若是 d 屬性不指定Z命令,則繪製線段,而不是封閉圖形 |
以上是 path 路徑中的所有指令,其中加粗部分爲經常使用基礎指令,相對來講比較好理解。每一個指令都有對應的小寫指令。例如M 10,10 有對應的 m 10,10 。大寫表明絕對位置,所謂絕對位置即對 SVG 畫布左上角原點的絕對。小寫表明相對位置,所謂相對位置是以當前畫筆所在位置進行定位。
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
<svg width="100%" height="100%">
<path d="M0 0 A 45 45, 0, 0, 0, 45 45 L 45 0 Z" fill="green"/>
</svg>
複製代碼
畫了張圖,幫助理解
按照圖中的步驟,咱們能夠畫出兩個圓都知足,因而再看到其中A指令有三個0咱們沒有解釋,回顧下 A 指令,並結合這張圖咱們能夠更好的理解
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
關於貝塞爾曲線,張老師這篇文章已經說得很是清楚了,說得很是易懂深度理解 SVG 路徑,推薦給但願更多瞭解 svg 路徑的同窗
基本圖形這塊相對比較好理解,咱們直接一張表總結下,不作過多贅述
圖形 | 標籤 | 模板 | 含義 |
---|---|---|---|
矩形 | < rect > | <rect x="60" y="10" rx="10" ry="10" width="30" height="30"/> |
x:起點橫座標,y:起點縱座標,rx:倒角x軸方向半徑,ry:倒角x軸方向半徑,width:寬度,height:高度 |
圓形 | < circle > | <circle cx="100" cy="100" r="50" fill="#fff"></circle> |
cx:圓心橫座標,cy:圓心縱座標,r:半徑 |
橢圓 | < ellipse > | <ellipse cx="75" cy="75" rx="20" ry="5"/> |
cx:橢圓心橫座標,cy:橢圓心縱座標,rx:橢圓x軸方向半徑,ry:橢圓y軸方向半徑 |
直線 | < line > | <line x1="10" x2="50" y1="110" y2="150"/> |
x1,y1:起點,x2,y2:終點 |
折線 | < polyline > | <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/> |
每兩個點以空格配對爲一個座標點,逗號隔開造成座標集合。連成折線。 |
多邊形 | < polygon > | <polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/> |
相似折線,不一樣的是,最後一個點會自動閉合第一個點,造成閉環。 |
symbol 標籤是咱們直播團隊 icon 管理平臺實現的核心技術點,它的做用說白話點就是至關因而一個元件,放在咱們的工具箱裏,就像下面這樣:
<svg class="svg-sprite">[工具箱]
<symbol id="icon-wave_add" viewBox="0 0 76 76"><path d="M38 0a4 4 0 014 4v30h30a4 4 0 110 8H41.999L42 72a4 4 0 11-8 0l-.001-30H4a4 4 0 110-8h30V4a4 4 0 014-4z" fill="currentColor" fill-rule="evenodd" opacity="none"></path></symbol>
<symbol id="icon-time" viewBox="0 0 10 10"><path d="M5 0a5 5 0 110 10A5 5 0 015 0zm0 1.5a.5.5 0 00-.5.5v3.02l.008.088a.5.5 0 00.238.343L7.02 6.794l.082.039a.5.5 0 00.603-.215l.039-.082a.5.5 0 00-.216-.603L5.5 4.735V2l-.008-.09A.5.5 0 005 1.5z" fill="rgba(153,153,153,1)" fill-rule="evenodd" class=" "></path></symbol>
<symbol id="icon-wave_delete" viewBox="0 0 40 40"><g fill="none" fill-rule="evenodd"><circle fill="#000" opacity="0.2" cx="20" cy="20" r="20"></circle><path stroke="#FFF" stroke-width="4" stroke-linecap="round" d="M13 13l14 14M27 13L13 27"></path></g></symbol>
</svg>
複製代碼
放一份就能夠無限引用。當它在工具箱裏時,咱們是看不到它的(頁面不會渲染它),只有咱們使用了<use>
標籤對其進行實例引用時,咱們才能夠在頁面上看到它:
<use xlink:href="#icon-time"></use>
複製代碼
咱們使用<symbol>
+ <use>
的組合,來實現svg雪碧圖,是否是以爲很easy。
有的同窗會有疑問,symbol 標籤和 g 標籤,放在 defs 裏彷彿都是在定義一個可複用的模塊,那麼二者之間有什麼區別呢?在個人理解裏,symbol 相對於g 標籤最大的不一樣在於 symbol 能夠給可複用代碼塊增長視圖屬性和視口屬性。方便在服用的時候直接調整到合適的運用(打印)尺寸。
其實關於 SVG 動畫,要說的有不少,本文咱們主要說一下 SVG 動畫的一些基本屬性和運用技巧
一、SMIL 驅動
二、JavaScript 驅動
三、CSS 驅動
技術 | 描述 | 備註 |
---|---|---|
SMIL | 很強大且純粹的標籤化動畫 | 雖然 Chrome 45之後棄用了SMIL,可是依然支持,各大瀏覽器的支持度都挺好的 |
CSS | CSS 還只能實現簡單的動畫 | offset-path 的兼容性不好。css 動畫不適合作交互性很強的動畫 |
JavaScript | 複雜動畫就要用到 JS 了,包括世面上的一些 SVG 動畫庫,也都是 JS 去實現的 |
SVG 是基於 XML 的矢量圖形描述語言,能夠近似理解成 HTML,因此能和 JS 以及 CSS 進行交互。 特 別是 CSS,咱們可使用 CSS3 來對 SVG 作動畫處理。可是要記住的是僅當 HTML 內聯包含 SVG 文件 時,咱們纔可使用 CSS 對其作樣式開發。本文咱們針對平時 CSS3 + HTML不容易實現, 而利用 SVG 能夠快速簡便實現的幾種場景作相應介紹
一、直線的變化
二、path 路徑實現圖形的平滑變幻
三、描邊動畫
四、指定軌跡運動
下面這張圖是一個 GIF 的 icon,體積大約是 156KB,壓縮以後。
若是咱們用 SVG 去實現的話。應該怎麼作呢。咱們分爲如下兩種方式,親測兼容性都 OK
總結&說明:
知識點1: SVG 中有不少屬性咱們是能夠用 CSS 去描述的。在基於 CSS 動畫三劍客(animation, transform, transition)的基礎上。咱們對一些屬性進行控制,就達到咱們想要的動畫效果。下面兩點值得說明:
<rect transform="rotate(45deg) ..." ... />
rect {
transform: rotate(45deg)
}
/** 行內的 transform 屬性,他的執行基點是在咱們 svg 元素的左上角也就是 svg 的座標原點。**/
/** 而 CSS 的 transform 原點則在元素自己的中心點。**/
複製代碼
CSS 可控屬性名 | 可實現場景 |
---|---|
理論上全部的顯示屬性,均可以使用 CSS 控制包括:好比 stroke-width、color、fill 等等 SVG 的顯示屬性 | 大部分的顯示樣式動態變化 |
x | 咱們知道矩形有 x、y 屬性,其含義是起始點,控制 x,咱們能夠動態控制矩形的X軸位移 |
y | 控制 y,咱們能夠動態控制矩形的 Y 軸向位移 |
cx | <circle cx="100" cy="100" r="50" fill="#fff" /> 這是一個圓形,控制 cx 能夠控制圓形(或者橢圓)的 X 軸位移 |
cy | 控制 cy 能夠控制圓形(或者橢圓)的 Y 軸位移 |
r | r 是圓的半徑,控制 r 能夠控制圓形的大小 |
rx | rx 是橢圓的 X 軸方向半徑,控制 rx 能夠控制橢圓的大小 |
ry | ry 是橢圓的 Y 軸方向半徑,控制 ry 能夠控制橢圓的大小 |
d | path 標籤的 d 屬性,控制 d 的路徑信息,能夠控制圖形的變幻(d 屬性在 safari 上是不支持 css 描述的。咱們下文會詳細的說明) |
PS:若是各位看官們在平常開發中,不清楚該屬性是否能夠經過 css 去控制,這邊給你們提供一個查詢連接 | 不支持 CSS 控制的 SVG 相關屬性 |
知識點2: 能夠利用 SMIL 對 SVG 作動畫處理,舉個例子,一樣的動畫效果,下面這段代碼不用 CSS 也能夠實現
export default function App() {
return (
<div className="App"> <svg width="100%" height="100%" viewBox="0 0 100% 100%"> {[1, 2, 3, 4, 5].map((it, index) => ( <line key={index} stroke="#000" strokeWidth="2" x1={15 + index * 5} y1="8" x2={15 + index * 5} y2="22" > <animate attributeName="y1" values="8; 15; 8" dur="1s" begin={`${(5 % (index + 1)) * 0.2}s`} repeatCount="indefinite" /> <animate attributeName="y2" values="22; 15; 22" dur="1s" begin={`${(5 % (index + 1)) * 0.2}s`} repeatCount="indefinite" /> </line> ))} </svg> </div>
);
}
複製代碼
那麼 什麼是 SVG 的 SMIL 呢?
這裏不想再對其作大篇幅的贅述,由於網上有不少文章都已經說得比較詳細了SMIL 動畫指欄、SVG SMIL animation 動畫詳解。 本文更想和你們交流的是在SMIL驅動和CSS驅動如何作選擇的問題。
雖說早在 Chrome 45,chrome 就已經官宣要棄用 SMIL,可是到目前位置,各大瀏覽器廠商對它的支持度是這樣的
Chrom 宣佈棄用 SMIL 是由於要支持 CSS Animation 與 Web Animation 的發展,因此咱們能夠理解爲當前是在一個過渡狀態,確實有一些暫時CSS 還無法支持或者支持度不好的動畫效果,SMIL 能夠輕鬆完成。可是基於 web 動畫技術發展的大趨勢,仍是建議咱們 SVG 動畫實現方案的選擇優先級是CSS 驅動 -> JS 驅動(咱們能夠採用一些框架,文末會給你們推薦一些好用的框架) -> SMIL 驅動
總結&說明:
知識點1: 經過對<path/>
d 屬性的控制,咱們能夠實現不少動畫效果,對於 d 屬性的控制目前有兩種方式,一種是經過 CSS 控制,另外一種是經過 SMIL 控制,可是目前因爲 safari 不支持用 CSS 來描述<path>
標籤的 d 屬性。因此在實現這種平滑的形狀變形效果上不推薦使用 CSS。更加推薦使用SMIL或者第三方庫去實現
基於 CSS:
path {
transition: ease all 0.3s; // 就像對dom同樣的對待svg
&.play { //這裏是播放狀態下的<path />路徑
d: path("M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z");
}
&.pause { //這裏是播放狀態下的<path />路徑
d: path(
"M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z"
);
}
}
複製代碼
基於 SMIL(即經過<animate>
實現對<path>
d 屬性的動態控制):
const pathMap = {
from: "M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z",
to: "M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z"
};
<svg class="icon" viewBox="0 0 120 120" width="400" height="400"> <path d="M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z" fill="#000000" > <animate attributeName="d" from={play ? pathMap.from : pathMap.to} to={play ? pathMap.to : pathMap.from} dur="0.3s" begin="indefinite" // 這裏設置開始時間爲無限以達到不自動播放的效果 fill="freeze" /> </path> </svg>
複製代碼
以上兩個 path 路徑的切換,就能夠帶來這種平滑過渡的效果。
知識點2:
咱們看到的圖形變幻,都須要遵循一個原則就是點數對齊原則,什麼意思呢?咱們能夠看下面的demo,五角星到 10 邊形(多邊形畫的很差,抱歉...😜)。,都是 10 個控制點到 10 個控制點的過分。因此效果平滑
而下圖的 10 個點到 3 個點就沒有這種平滑的過渡效果了(固然如今不少的 SVG 動畫框架已經解決了這個問題。見文末的框架推薦 )
總結&說明:
知識點1:
相似的描邊動畫咱們能夠拿來作不少效果,好比各類形狀的進度條、好比文字的描邊、好比霓虹燈流水燈光等等流動動畫效果。而描邊動畫的核心點就在於 SVG 的兩個顯示屬性分別是 stroke-dasharray、stroke-dashoffset,咱們上文說了,幾乎全部的顯示屬性均可以用 CSS 去控制,因此這種動畫,建議使用 CSS 去開發。
屬性 | 值舉例 | 描述 | 支持範圍 |
---|---|---|---|
stroke-dasharray | 1 3 4 4 | 它的值是一個序列,能夠傳入多個值,分別指定描邊短線的長度和描邊線間距,多個值依次循環,若是傳入3個值,相似於 stroke-dasharray: 1,2,3。則會自動複製一份再生效 | <circle>, <ellipse>, <line>, <mesh>, <path>, <polygon>, <polyline>, <rect> <altGlyph>, <altGlyphDef>, <altGlyphItem>, <glyph>, <glyphRef>, <textPath>, <text>, <tref>, <tspan> |
stroke-dashoffset | 10 | 描邊線段的起始位置距離圖形繪製起點的偏移量。正負值能夠決定順時針仍是逆時針走向 | 跟stroke-dasharray一致 |
設想一個場景,一個倒計時須要從 100 到 0,對應的視覺效果也就是從全描邊到無描邊。那麼咱們初始狀態將 stroke-dasharray 的第一個值設爲 2πr (周長),第二個值設也設爲 2πr (周長)。那麼咱們會獲得一個整圓。
這時若是咱們把圓展開就能看到這樣的場景
因此要實現進度的動態變化其實有兩種方案
第一種是將stroke-dasharray的第一個值從2πr(周長)調整到0。原展開圖中的黑色部分沒有了(能夠理解爲變成了一個點以下圖,看不見了),只剩下虛線部分是空白間隙了。
第二種是將stroke-dashoffset的值從0調整到-2πr(或者增長到2πr)。對比第一張圖成下圖的樣子
知識點2:
在實際開發中,咱們會遇到一些比較複雜的圖形須要作描邊,這個時候咱們沒辦法去獲得它的周長是多少,這時候分兩種場景處理。一種是在CSS裏咱們能夠將stroke-dasharray的第二個值設置成一個很是大的數字,而後再去調整第一個值好比:
path {
stroke-dasharray: 0(調整到合適的值) 99999999999999
}
複製代碼
若是在js裏咱們須要動態去獲取周長的話,SVG提供了原生的api能夠去獲取path的周長。
const inPath = document.getElementById("inner-path");
console.log(inPath.getTotalLength());
複製代碼
ps:有些資料說該方法只能用於<path />
,可是筆者親測了在safair和chrome上,基本能夠支持全部的基礎圖形以及<path />
,可是<text />
不支持,瀏覽器會報not a function。
既然說到了getTotalLength()
,那麼順帶說下getPointAtLength()
。getPointAtLength,顧名思義就是根據距離獲取點座標。意思就是根據到起始點的距離,獲取該指定距離對應的點的座標。座標系原點爲該圖形的起始點。在一些指向型的動畫上咱們可能會運用到這個api。
總結&說明:
{/* 咱們將整個飛機圖形元件用g標籤包起 */}
<g transform="translate(-100, -35) scale(0.1)">
<path d="M164.485419 578.709313L196.274694 794.731891c0.722484 5.53904 8.188147 7.224835 11.078081 2.408278l75.860772-121.377234 740.063969-363.409219L164.485419 578.709313z" fill="#F68206" ></path>
<path d="M2.167451 440.233302l159.668861 132.214487 857.828787-260.334901zM289.475071 679.375353l191.217309 153.407337 542.344309-518.743179z" fill="#FF9900" ></path>
<path d="M204.222013 800.030103l125.23048-80.677328-48.888053-39.014111-76.342427 118.4873" fill="#D3650B" ></path>
{/* 而後在這裏,咱們利用animateMotion,去作這個軌跡運動 */}
<animateMotion path="M 0 450 Q 150 50 250 50 Q 350 0 400 50 Q 500 50 450 200 C 300 350 250 200 500 50 C 600 50 750 200 650 250 A 50 50 0 1 1 800 50 " begin="0s" rotate="auto" dur="20s" repeatCount="indefinite" />
</g>
複製代碼
這裏咱們用到了SMIL裏的<animateMotion />
,animateMotion裏的path屬性,咱們也能夠像這樣去使用
<defs>
<path id="theMotionPath" d="xxx" />
</defs>
<animateMotion>
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
複製代碼
實際生產中,咱們這種軌跡運動的需求,是建議使用SMIL去實現的,固然CSS也是有實現方案的《使用CSS offset-path讓元素沿着不規則路徑運動》。可是CSS的兼容實在不敢恭維,勸退一波。
1、 建議將CSS動畫用於無變形的過渡或簡單動畫。尤爲是在硬件加速時。CSS不須要加載其餘資源(通常指三方庫),而且懸停時的小變換能夠爲交互帶來更好的效果。特別是當你不須要3d、物理體感、或進行大量堆疊動畫效果時建議選用CSS。另外,CSS方便調試也是很大的一個優點。
2、對於較長的動畫,開發時會變得很是複雜且須要花精力去調試,而CSS調整時間尺度很困難,尤爲是當你須要操縱一些細微幀時,我的以爲SMIL更合適作有序的,複雜的堆疊動畫羣的場景。
3、對於變形的動畫,建議使用SMIL或者第三方庫。推薦的比較優秀的三方庫有如下幾個。
庫名 | 描述 |
---|---|
GSAP | 全稱是GreenSock Animation Platform,之前流行用 flash 的時候,GSAP就叱吒江湖的存在,GSAP有兩個版本一個是 flash 版本,一個是 javascript 版本,也就是咱們說的 GSAP js。GSAP 速度快。GSAP專門優化了動畫性能,使之實現和css同樣的高性能動畫效果;輕量與模塊化; |
Snap.svg、SVG.js、Velocity.js | 這三個庫一直會被開發者拿來對比,基本上會用jQuery,就會使用這三個庫,也就是說入手友好,Snap.svg 更偏向於支持現代瀏覽器,因此它的體量也會小一些。對比 Snap.svg 來看 SVG.js ,SVG.js 的寫法更加的清晰,使用時會有更好的體驗,且自稱提供接近完整的 SVG 規範覆蓋。Snap.svg 風格就更像一個俠客,寫起來會很瀟灑可是很差讀,Velocity 也很強大,簡單易用、高性能、功能豐富 |
anime.js | anime.js 雖然功能沒有 GASP 強大,可是體積很樂觀,gzip壓縮完只有9kb左右,知足平常需求開發仍是足夠的 |
D3 | Data-Driven Documents 顧名思義,更加適合用於建立數據可視化圖形場景去使用 |
4、如何使用 SMIL 進行硬件加速,使用 代替,並設置 x、y、z 值(z 爲 0)。原理與 CSS 相似,這會將元素移到它本身的層,從而在其發生運動時不會從新繪製。
本文發佈自 網易雲音樂大前端團隊,文章未經受權禁止任何形式的轉載。咱們常年招收前端、iOS、Android,若是你準備換工做,又剛好喜歡雲音樂,那就加入咱們 grp.music-fe(at)corp.netease.com!