數據可視化系列--svg入門基礎(一)

一、前言

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()方法轉換成pngjpg圖片。

 

三、作用於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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章