TL,TR
SVG其相關特性遠比想象中要強,本文首先介紹下SVG的相關定義、特點和Demo,接下來會介紹它的相關語法和動畫,最後告訴大家如何使用和優化SVG。
確保大家一小時內可以開車上路….. 來不及解釋了,快上車…..
一、簡介
定義
SVG(Scalable Vector Graphics)是可縮放向量圖形的縮寫,基於可擴充套件標記語言XML來描述二維向量圖形的一種圖形格式,由W3C制定,是一個開放標準。
特點
現在我們可以使用PNG、JPG來展示靜態的圖片,使用CSS3、JS或者挫一點的GIF來表示動畫,厲害一點我們可以使用Canvas來繪圖,那麼為什麼還要使用SVG呢?
- 和PNG、GIF比較起來,檔案體積更小,且可壓縮性強;
- 由於採用XML描述,可以輕易的被讀取和修改,描述性更強;
- 在放大或改變尺寸的情況下其圖形質量不會有所損失,與解析度無關,是可伸縮的;
- SVG是面向未來 (W3C 標準)的,同時瀏覽器相容性好;
- 使用CSS 和 JS能很方便的進行控制,同時可以很輕易地描述路徑動畫;
- 和Canvas相比
- Canvas基於畫素,提供2D繪製函式,是一種HTML元素型別,依賴於HTML,只能通過指令碼來繪製圖形,Canvas提供的功能比較原始,適合畫素處理,動態渲染和大資料量繪製的應用場景;
- SVG為向量,提供一系列圖形元素(Rect, Path, Circle, Line …),還有完整的動畫,事件機制,本身可以獨立使用,也可以嵌入到HTML中,SVG很早就成為了國際標準,功能更完善,適合靜態圖片展示,高保真文件檢視和列印的應用場景;
Demo
使用SVG可以做出什麼比較好玩的東西呢?
上週團隊(??臭不要臉插個很硬的廣告,阿里飛豬前端團隊在招人啦,詳細:飛豬尋覓前端同學)有一個小的hackthon,就是通過程式碼來畫這個Loading GIF,然後就邊學邊用SVG寫了一個相同的loadng,體積從之前GIF的33KB變成了864B的SVG,詳細見下面:
See the Pen Fliggy Loading by Tw93 (@tw93) on CodePen.
另外一些有趣的SVG可以檢視30 Awesome SVG Animation For Your Inspiration這裡。
二、座標定位
學習SVG語法之前,我們可以來了解下SVG的座標定位,這種座標系統和我們小時候學習的繪圖座標是相反的,但是在HTML中都是用如下方式定位。即以頁面的左上角為(0,0)座標點,座標以畫素為單位,x軸正方向是向右,y軸正方向是向下。
三、元素
基礎形狀
SVG中提供了很多基礎元素可以用來繪製基礎的形狀,譬如矩形、圓形、橢圓、多邊形、折線、線條、路徑等,同時可以將這些基礎形狀組合繪製出複雜的影象。
以上基礎形狀的展示效果可以通過這些程式碼表示出來,詳細見下:
See the Pen SVG Basic_Shapes by Tw93 (@tw93) on CodePen.
其他重要元素
- svg:SVG的根元素,並且可以相互巢狀;
- g:用來將SVG中的元素進行分組操作,分組後可以看成一個單獨的形狀,統一進行轉換,同時g元素的樣式可以被子元素繼承,但是它沒有X,Y屬性,不過可以通過transform來移動它;
- def:用於定義在SVG中可重用的元素,def元素不會直接展示出來,可以通過use元素來引用;
- use:通過它來複用def元素,也包括、元素,使用即可呼叫;
- text:可以用它來實現word中的那種“藝術字”,很神奇的一個功能;
- image:用它可以在SVG中巢狀對應的圖片,並可以在圖片上和周圍做對應的處理;
四、樣式
可以類比於在切頁面過程中,我們需要將我們畫好的框框進行描邊、填色、有時候還要加入漸變效果、轉換、裁剪、等效果。
輪廓 stroke
stroke用於設定繪製物件線條的顏色,同時stroke有如下屬性:
- stroke-width:設定輪廓的寬度;
- stroke-linecap:設定輪廓結尾處的渲染方式,value有butt(直接一刀切斷)、square(保留一點切斷)、round(圓弧切斷) 3個設定值;
- stroke-linejoin:用於設定兩條線之間的連線方式,value有miter(尖角連線)、round(圓弧連線)、bevel(切斷連線) 3個設定值;
- stroke-opacity:用於設定描邊的不透明度;
- stroke-dasharray + stroke-dashoffset:stroke-dasharray用於使用虛線呈現SVG形狀的描邊,需要提供一個數值陣列來描述,定義破折號和空格的長度;stroke-dashoffset用於設定虛線模式中的開始點;
填充 fill
fill用來描述SVG物件內部的顏色,除此還有如下兩個屬性:
- fill-opacity:用於設定填充顏色的不透明度;
- fill-rule:用於設定填充的方式,value有nonzero、evenodd 兩個值;
- nonzero:從一個點往任何方向上繪製一條射線,形狀中的路徑每次穿過此射線時,如果路徑從左到右穿過射線,則計數器加1,如果路徑從右到左穿過射線,則計數器減1。計數器總數為0時候,則該點被認為在路徑外。如果計數器非0,則該點被認為在路徑內;
- evenodd:從一個點往任何方向上繪製一條射線。每次路徑穿過射線,計數器加1。如果總數是偶數,則點在外部。如果總計數為奇數,點在形狀內;
變換 transform
此屬性和css3中的transform相類似,有translate、rotate、scale、skew(skewX和skew函式使x軸和y軸傾斜)、matrix(矩陣變換,請聯想大學線性代數 ???)這些變換,同時可以將它們組合進行變換。
此外還有漸變、遮罩、裁剪等屬性,詳細請參考:linearGradient,mask,clipPath。
五、動畫
在SVG中動畫元素主要分成如下4類,同時也可以自由組合。
- set:用於設定延遲,譬如設定5s後元素位置顏色變化,但是此元素沒有動畫效果;
- animate:基礎動畫屬性,用於實現單屬性的動畫過度效果;
- animateTransform:實現transform變換動畫效果,可以類比CSS3中的transform;
- animateMotion:實現路徑動畫效果,讓元素沿著對於path運動;
有了元素以後還需要有對應的屬性用來表示動畫的特徵,譬如:要動畫的元素屬性名稱、起始值、結束值、變化值、開始時間、結束時間、重複次數、動畫速度曲線函式等等。
動畫有很多地方都很新鮮,大家可以多多嘗試。
See the Pen SVG animation by Tw93 (@tw93) on CodePen.
六、使用方式
我們可以使用如下4種常用的方式來載入我們的SVG,此處可以將svg轉換成base64的方式。
通過Img標籤:
1 |
<img src="tw93.svg" alt="Hello SVG" height="65" width="68"> |
通過CSS background:
1 2 3 |
.logo { background: url("data:image/svg+xml;base64,[data]"); } |
通過object:
1 2 3 |
<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]"> fallback </object> |
直接內建到Html中:
1 2 3 4 |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65"> <path fill="#1A374D" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/> <path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/> </svg> |
前三種方式常用於SVG圖片已經定型,並且改動很少的情況,通過獨立的SVG檔案更好進行管理,同時可以減少HTML元素;內建的方式常用於SVG需要常修改或者還沒有確定的情況,更加變化修改和維護。
七、優化和工具
SVGO
SVG Optimizer is a Nodejs-based tool for optimizing SVG vector graphics files.
SVGO一個比較厲害的壓縮優化SVG的工具,可以將我們編寫的SVG中的無用資訊,同時對程式碼進行壓縮,專案地址:https://github.com/svg/svgo。
SVGOMG
SVGOMG是SVGO的視覺化介面工具,操作起來很方便,同時還提供了一些其他有用的功能,展示地址:SVGOMG – SVGO’s Missing GUI
Snap.svg
The JavaScript SVG library for the modern web.
Snap.svg是一個可以使你操縱SVG資源和jQuery操作DOM一樣簡單的類庫,可以寫出更加複雜的SVG效果,同時文件超級齊全,推薦給想深入瞭解的同學,專案地址:Snap.svg – Home,下圖就是使用Snap.svg來實現的。
See the Pen Interactive Illustration via Snap by Tw93 (@tw93) on CodePen.
Convert image to the SVG format
我們可以通過這個轉換平臺,將普通圖片轉成SVG的格式,但是此處轉換可能結果不是我們想要的,但是可以將其當做初成品,在此基礎上在進行調整優化,最終實現SVG的轉換。平臺地址:http://image.online-convert.com/convert-to-svg
完,歡迎大家指教和討論。