一、前言
1、SVG(Scalable Vector Graphics)可伸縮矢量圖形
特點:
(1)使用xml格式來定義圖形;
(2)用來定義web上的使用的矢量圖;
(3)改變圖像尺寸,圖片質量不受損;
(4)所有元素屬性可以使用動畫;
(5)繼承了W3C標準,在html中使用方式,html直接嵌入svg內容,或者直接引入svg文件。
/* svg標籤,這裏的rect爲矩形,在後面的圖形元素中會詳細說明 */
<svg width="200" height="200">
<rect width="20" height="20" fill="red"></rect>
</svg>
/* 引入後綴名爲.svg的文件 */
<img src="demo.svg" alt="測試svg圖片">
注意:svg爲inline水平元素。且需要繪製的所有圖形都應被包含在<svg></svg>
標籤內。
2、SVG座標系
特點:(1)y軸向下;(2)順時針方向的角度是正值。
注意:元素的所有操作都是相對自身座標系進行的
3、顏色RGB和HSL
RGB: 三個分量:紅色、綠色、藍色,每個分量的取值範圍[0, 255],優點是顯示器更容易解析。
HSL: 三個分量:顏色h、飽和度s%、亮度l%,每個分量的取值範圍分別是[0, 359], [0, 100%], [0, 100%],,其中,h=0表示紅色, h=0表示120綠色,h=0表示240 藍色。
基於HSL的配色方案:http://paletton.com/
二、特殊元素
1、foreignObject
foreignObject元素通常被用來在svg代碼中嵌入html節點。注意:該屬性對IE不支持。<foreignObject>
元素的作用是可以在其中使用具有其它XML命名空間的XML元素,換句話說藉助<foreignObject>
標籤,我們可以直接在SVG內部嵌入XHTML元素。通常會與標籤一起使用,在用戶瀏覽器不支持時,告知用戶。
舉個例子:
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="120" height="50">
<body xmlns="http://www.w3.org/1999/xhtml">
<p>文字測試foreignObject的功能</p>
</body>
</foreignObject>
</svg>
可以看到<foreignObject>
標籤裏面有一個設置了xmlns="http://www.w3.org/1999/xhtml"
命名空間的<body>
標籤,此時<body>
標籤及其子標籤都會按照XHTML標準渲染,實現了SVG和XHTML的混合使用。
這種混合特性有什麼作用呢?作用很多,其中之一就是輕鬆實現SVG內的文本自動換行。
1.1文本自動換行
SVG要實現文本換行,往往需要手動阻斷
<svg xmlns="http://www.w3.org/2000/svg">
<text font-size="12">
<tspan x="0" y="10">一段需要word wrap</tspan>
<tspan x="0" y="26">的文字。</tspan>
</text>
</svg>
需要2
個<tspan>
元素,這一點都不工程。
但是如果使用<foreignObject>
元素,則自動換行就是小菜:
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="120" height="50">
<body xmlns="http://www.w3.org/1999/xhtml">
<p style="font-size:12px;margin:0;">一段需要word wrap的文字。</p>
</body>
</foreignObject>
</svg>
1.2將頁面上的DOM元素輕鬆變成圖片
SVG <foreignObject>
元素還有其他更高級的應用,就是可以將頁面上的DOM元素輕鬆變成圖片。
原理:
1、獲取對應DOM元素的outerHTML代碼;
2、放在<foreignObject>元素中;
3、圖片方式顯示我們的SVG圖形;
4、上一步的圖片本質還是SVG,我們可以藉助canvas
drawImage()
方法將圖片放在畫布上,然後使用canvas.toDataURL()
方法轉換成png
或jpg
圖片。
三、作用於svg標籤的屬性
1、viewport
表示svg的可見區域的大小:width和height,控制svg的寬度和高度
2、viewBox
定義用戶視野的位置以及大小,即定義用來觀察SVG視圖一個矩形區域,更形象的解釋就是:SVG就像是我們的顯示器屏幕,viewBox就是截屏工具選中的那個框框,最終的呈現就是把框框中的截屏內容再次在顯示器中全屏顯示!
如:viewBox ='20 20 100 100',前兩個參數表示viewBox視野相對svg視圖的x y座標,後兩個參數表示viewBox的大小。
與svg實際大小的關係如下:
如上圖所示,用戶可以看到的部分是藍色的星星,而星星的另一側是看不到的。
viewBox的使用案例:
1、繪製矩形
<svg width="200" height="200" style="border: 2px solid #58a">
<rect x="30" y="30" width="100" height="100" fill="#fb3" stroke="none"></rect>
</svg>
2、增加視野viewBox viewBox='0 0 100 100',相當於用戶只能看到SVG視圖中viewBox定義的區域,即下圖紅色框內區域:
viewBox="x, y, width, height" // x:左上角橫座標,y:左上角縱座標,width:寬度,height:高度
body>
<svg width="200" height="200" style="border:2px solid #58a" viewBox='0 0 100 100'>
<rect x="30" y="30" width="200" height="200" fill="#fb3" stroke="none"></rect>
</svg>
最終效果圖:
3、preserveAspectRatio屬性
這個屬性也是作用於<svg>元素上,且作用對象都是viewBox。
比如:
preserveAspectRatio="xMidYMid meet"
屬性值爲空格分隔的兩個值組合而成。第一個值表示:viewBox如何viePort對齊;第二個值表示:如何維持高寬比(可以爲空)。
其中,第一個值又分爲兩個部分組成。前半部分表示x方向的對齊。後半部分表示y方向對齊。
值 | 含義 |
xMin | viewport和viewBox左邊對齊 |
xMid | viewport和viewBox的x軸中心對齊 |
xMax | viewport和vieBox右邊對齊 |
YMin | viewport和viewBox上邊緣對齊。注意:Y是大寫 |
YMid | viewport和viewBox的y軸中心點對齊。注意:Y是大寫 |
YMax | viewport和viewBox下邊緣對齊。注意:Y是大寫 |
xMaxYMax表示右-下
xMidYMid表示中-中
第二個值屬性值支持
值 | 含義 |
meet | 保持縱橫比縮放viewBox適應viewport,受 |
slice | 保持縱橫比,同時比例小的方向放大填滿viewport,攻 |
none | 扭曲縱橫比,充分適應viewport,變態 |
1、圖1:紅色區域爲不設置preserveaspectRatio時的可視區域;
2、圖2: 採用與x軸左邊對齊、與y軸上邊緣對齊的方式,保持縱橫比縮放;
3、圖3:保持縱橫比的同時,以比例小的方向即x軸等比放大,填充svg區域
4、圖4:preserveaspectRatio="none",變形充分適應svg
四、作用於svg內部元素的樣式
svg支持css選擇器給元素添加樣式
/* 定義樣式 */
.rectStyle {
fill: yellow;
}
<svg width="200" height="200">
<rect class="rectStyle" width="20" height="20"></rect>
</svg>
也可以直接在元素中設置樣式:
<svg width="200" height="200">
<rect width="20" height="20" fill="yellow"></rect>
</svg>
或者寫成style
<svg width="200" height="200">
<rect style="fill: yellow;" width="20" height="20"></rect>
</svg>
常見的樣式說明:
1、填充
(1)fill:定義填充顏色和文字顏色;
(2)fill-opacity:定義填充顏色的透明度;
(3)fill-rule:指定填充規則,符合填充規則纔可被填充,取值:[nonzero | evenodd | inherit]
,默認值爲nonzero。
nonzero: 該規則判斷點任意方向的射線與圖形路徑的相交情況,默認爲數值0,射線從左到右時,每穿過一條路徑,數值加1;從右到左時,每穿過一條路徑,數值減1,最後結果若爲0,則表示點不在圖形內部,不能填充。
evenodd:該規則判斷點任意方向的射線與圖形路徑的相交情況,相交個數爲奇數,則點在圖形內部,可進行填充;反之在外部,不進行填充。
好像比較難理解這個,fill-rule到底是爲了解決什麼問題?
我們看上圖,圖中有一個路徑A-B-C-D-E-F-G-H-I,當我們用fill填充它的時候,我們會發現其中有一個重疊的區域S,那麼這個重疊的區域到底填不填充呢?這,就是fill-rule所幹的事。
分析:沿着A-B-C-D-E-F-G-H-I方向走,我們會發現重疊區域S外部爲A-B-C-D-A,形成方向爲順時針方向。重疊外部區域S的形成方向爲逆時針H-I-A,所以重疊區域S不顯示。這個和fill-rule設置無關,這是默認的。
來看一下經典的五角星問題:
相同的,這裏有一個重疊區域S,不過如何才能知道是重疊區域呢?其實很簡單,就是重疊區域的外面還有東西,而它們都還在整個形狀之內。
我們可以發現五角星的重疊區域S的形成方向和外部是一樣的,這種情況下,fill-rule就起作用了,如果是nonzero,區域S是顯示的,如果是evenodd,區域S則不顯示。
2、邊框
(1)stroke:邊框顏色;
(2)stroke-width:邊框寬度;
(3)stroke-opacity:邊框透明,取值[0,1];
(4)stroke-linecap:單條線端點樣式,一般應用於直線或者路徑,取值:[ butt | square | round ]
,分別是對接、方形和圓形
(5)stroke-dasharray:虛線邊框,可以設置每段虛線的長度和間隔,之間使用逗號分隔或者空格分隔,如:
stroke-dasharray="10, 5, 5, 10"
(6)stroke-dashoffset:設置虛線描邊偏移量,使圖案向前移動
<svg width="200" height="200" viewBox='0 0 300 300'>
<line x1="20" y1="20" x2="120" y2="20"
stroke="red" stroke-width="5" stroke-linecap="butt"
stroke-dasharray="20 5 5 10">
</line>
<line x1="20" y1="60" x2="120" y2="60"
stroke="red" stroke-width="5" stroke-linecap="butt"
stroke-dasharray="20 5 5 10" stroke-dashoffset="10">
</line>
</svg>
虛線的樣式爲 20 5 5 10
,偏移量爲10
,根據下圖可發現第二個虛線,整體向前移動了10個單位
(7)sroke-linejoin:兩條線段之間銜接點的樣式,取值:[ miter | round | bevel ]
,分別是尖角(圖左一)、圓角(圖左二)和斜角(圖左三)
(8)sroke-miterlimit:默認值4,當miterLength / stroke-width < stroke-miterlimit
時,stroke-linejoin
值會變成換成bevel
斜角。如下圖中,stroke-width爲15,根據計算公式,miterLength / stroke-width 約等於5.2,即當stroke-miterlimit
小於6時,stroke-linejoin值會變成bevel斜角。
3、透明度
opacity:定義整個圖形的透明度
4、字體
(1)font-size:字體大小;
(2)font-family:字體系列的名稱;
(3)font-weight:字體粗細;
(4)font-style:字體樣式,斜體和正常;
(5)text-decoration:下劃線樣式;
(6)text-anchor:設置文本的排列屬性,屬性值[start | middle | end | inherit]
,如:middle表示,將文字定位原點移動至文字中心。
5、變換
基礎概念同css。
(1)transform:同css,默認是左上角爲旋轉中心,如:transform="rotate(30)";
(2)transform-origin:同css,設置旋轉的操作中心;
(3)rotate:設置文字元素的旋轉角度,正值爲順時針旋轉,注意區分rotate和transform中的rotate,如rotate="30"
而transform中的rotate是對整個元素進行旋轉操作。
<svg width="200" height="200">
<text x="10" y="10" dx="10" dy="10" textLength="100" rotate="20">示例文字1</text>
</svg>
<svg width="200" height="200">
<text x="10" y="10" dx="10" dy="10" textLength="100" transform="rotate(20)">示例文字2</text>
</svg>
五、參考
1、http://www.runoob.http://www.runoob.com/svg/svg-tutorial.html
2、http://qiutianaimeili.com/html/page/2018/04/08sh1vbv35yr.html