SVG 入門指南(看完,對SVG結構不在陌生)

我的專欄 ES6 深刻淺出已上線,深刻ES6 ,經過案例學習掌握 ES6 中新特性一些使用技巧及原理,持續更新中,←點擊可訂閱。css

點贊再看,養成習慣

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。html

SVG 簡介

SVG,便可縮放矢量圖形(Scalable Vector Graphics),是一種 XML 應用,能夠以一種簡潔、可移植的形式表示圖形信息。目前,人們對 SVG 愈來愈感興趣。大多數現代瀏覽器都能顯示 SVG 圖形,而且大多數矢量繪圖軟件都能導出 SVG 圖形。SVG 主要能夠歸納爲如下幾點:git

  • SVG 指可伸縮矢量圖形
  • SVG 用來定義網絡的基於矢量的圖形
  • SVG 使用 XML 格式定義圖形
  • SVG 圖像在放大或改變尺寸的狀況下其圖形質量不會有所損失
  • SVG 是萬維網聯盟的標準
  • SVG 與諸如 DOM 和 XSL 之類的 W3C 標準是一個總體

SVG 的應用

  1. 圖表視圖(echart)、地圖視圖(WEB-GIS)
  2. 形象(AI)的全網應用
  3. UI 產品的設計
  4. SVG 動畫

SVG 瀏覽器的兼容狀況

clipboard.png

SVG 與 Canvas 區別

clipboard.png

圖形系統

計算機中描述圖形信息的兩大系統是柵格圖形和矢量圖形。github

柵格圖形

在柵格圖形系統中,圖像被表示爲圖片元素或者像素的長方形數組以下圖片所示。每一個像素用其 RGB 顏色值或者顏色表內的索引表示。這一系列也稱爲 位圖,經過以某種壓縮格式存儲。因爲大多數現代顯示設備也是柵格設備,顯示圖像時僅須要一個閱讀器將位圖解壓並將它傳輸到屏幕上。面試

clipboard.png

矢量圖形

矢量圖是基於數學的描述,以下圖的多啦A夢,他的頭是一條怎麼樣的貝塞爾曲線,它的參數是什麼及用什麼顏色來填充貝塞爾曲線,經過這種方式描述圖片就是適量圖segmentfault

想象一下在一張繪圖紙上做圖的過程,柵格圖形的工做就像是描述哪一個方格應該填充什麼顏色,而矢量圖形的工做則像是描述要繪製從某個點到另外一個點的直線或曲線。數組

建立 SVG 圖像

SVG 文檔基本結構

以下所示,是一個 SVG 文檔結構:瀏覽器

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
</svg>

根元素 <svg> 以像素爲單位定義了整個圖像的 widthheight,還經過 xmlns 屬性定義了 SVG 的命名空間。<title> 元素的內容能夠被閱讀器顯示在標題欄上或者是做爲鼠標指針指向圖像時的提示, <desc> 元素容許我們爲圖像定義完整的描述信息。微信

基本形狀和屬性

基本圖形網絡

<rect><circle><ellipse><line><polyline><polygon>

基本屬性

fillstrokestroke-widthtransform

基本形狀 --- 圓形

clipboard.png

我們能夠經過 <circle> 元素來繪製貓的臉部。元素屬性的中心點 x 座標和 y 座標覺得半徑。點(0,0) 爲圖像左上角。水平向右移動時 x 座標增大,垂直向下移動時 y 座標增大。爲了不一些誤會,API 語文就很明確了,點 (cx, cy) 就表示圓心的位置,r 表示圓的半徑。

繪圖的顏色是表現的一部分,表現信息包含在 style 屬性中,這裏的輪廓顏色爲黑色,填充顏色爲 none 以使貓的臉部透明。

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
</svg>

clipboard.png

指定樣式的屬性

接着在添加兩個圓表示兩個眼睛。上面的 strokefill 是寫在 style 裏面的,可是 SVG 也容許我們使用單獨的屬性,而不用所有寫在 style 內,以下所示:

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
</svg>

clipboard.png

圖形對象分組

接着使用兩個 <line> 元素在貓的右臉上添加鬍鬚,先看下線的示意圖:

clipboard.png

這很好理解,就很少說了。 這裏咱們須要把鬍鬚做爲一個部件,幷包裝在分組元素 <g> (後面會講)裏面,而後給下 id ,以下所示:

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <g id='whiskers'>
    <line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
    <line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
  </g>
</svg>

clipboard.png

圖形對象分組

接着使用 <use> 複用鬍鬚分組並將它變換(transfrom) 爲左側鬍鬚,以下圖所示,首先在 scale 變換中對 x 座標乘以 -1,翻轉座標系統。這意味原始座標系統中的點(75, 95) 如今位於 (-75, 95)。接着經過 translate 向左平移調整對應的位置。

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <g id='whiskers'>
    <line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
    <line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
  </g>
  <use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
</svg>

clipboard.png

其餘基本圖形

以下圖所示,我們使用 <polyline> 元素構建嘴和耳朵,它接受一對 xy 座標爲 points 屬性的值。你可使用空格或者逗號分隔這些數值。

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <g id='whiskers'>
    <line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
    <line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
  </g>
  <use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
  <!-- 耳朵 -->
  <polyline points='108 62,90 10, 70 45, 50, 10, 32, 62'
    style='stroke:black; fill:none' />
  <!-- 嘴 -->
  <polyline points='35 110,45 120, 95 120, 105, 110'
    style='stroke:black; fill:none'/>
</svg>

clipboard.png

路徑

全部的基本形狀都是通用的 <path> 元素的快捷寫法。接着使用 <path> 元素爲貓添加鼻子。以下所示的代碼,翻譯過來就是 "移動到座標(75, 90)。繪製一條到座標(65,90) 的直線。而後以 x 半徑爲 5y 半徑爲 10 繪製一個橢圓,最後回到座標 (75, 90) 處"

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <g id='whiskers'>
    <line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
    <line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
  </g>
  <use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
  <!-- 耳朵 -->
  <polyline points='108 62,90 10, 70 45, 50, 10, 32, 62'
    style='stroke:black; fill:none' />
  <!-- 嘴 -->
  <polyline points='35 110,45 120, 95 120, 105, 110'
    style='stroke:black; fill:none'/>
  <!-- 鼻子 -->
  <path d='M 75 90 L 65 90 A 5 10 0 0 0 75 90'
    style='stroke:black; fill:#ffcccc'
  />
</svg>

clipboard.png

路徑

因爲這只是一個簡單的圖形,用戶可能看不出這是一隻貓,因此我們可使用 <text> 元素添加一些文本註釋。在 <text> 元素中,x 和 y 屬性用於指定文本的位置,以下所示:

<svg width='140' height='170' 
  xmlns='http://wwww.w3.org/2000/svg'
  xmlns:xlink='http://wwww.w3.org/1999/xlink'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
  <circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
  <g id='whiskers'>
    <line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
    <line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
  </g>
  <use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
  <!-- 耳朵 -->
  <polyline points='108 62,90 10, 70 45, 50, 10, 32, 62'
    style='stroke:black; fill:none' />
  <!-- 嘴 -->
  <polyline points='35 110,45 120, 95 120, 105, 110'
    style='stroke:black; fill:none'/>
  <!-- 鼻子 -->
  <path d='M 75 90 L 65 90 A 5 10 0 0 0 75 90'
    style='stroke:black; fill:#ffcccc'
  />
  <text x="60" y="165" style='font-family:sans-serif;font-size: 14pt;
    stroke:none; fill: black;
  '>Cat</text>

clipboard.png

若是看不懂代碼,不要緊,後面幾章節會深刻這些基本及屬性。

在網頁中使用 SVG

SVG 是一種圖件格式,所以可使用與其餘圖像類型相同的方式包含在 HTML 頁面中。具體能夠採用兩種方法:將圖像包含在 <img> 元素內(當圖像是頁面的基本組成部分時,推薦這種方式);或者將圖像做爲另外一個元素的 CSS 樣式屬性插入(當圖像主要用來裝飾時,推薦這種方式)。

在 <img> 元素內包含 SVG

<img> 元素內包含 SVG 圖像很是簡單,只需設置 src 指向 SVG 文件位置便可。以下:

<img src='cat.svg' alt=''/>

在 CSS 中包含 SVG

可使用 background-image 屬性來顯示 SVG,若是沒有固有尺寸, SVG 會被縮放爲元素高度和寬度的 100%,以下所示:

div.background-cat {
  background-image: url('cat.svg');
  background-size: 100% 100%;
}

使用 object 標籤引入 SVG (不推薦)

<object> 元素的 type 屬性表示要嵌入的文件類型。這個屬性應該是一個有效的網絡媒體類型(一般被稱爲 MIME 類型)。對於 SVG,使用 type='image/svg+xml'。以下所示:

<object data='cat.svg' type='image/svg+xml' 
  width='100' height='100'/>

在網頁中直接使用 SVG 標籤

直接引用 svg 定便可,以下所示:

<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在這裏繪製圖像 -->
  <circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
</svg>

SVG 的視窗,視野和全局(世界)

視窗

SVG的屬性widthheight來控制視窗的大小,也稱爲SVG容器

世界

SVG裏面的代碼,就是對SVG世界的定義

視野

世界是無窮大的,視野是觀察世界的一個矩形區域。以下圖所示

clipboard.png

世界不可變,而視野是能夠改變的。在SVG中,提供了viewBoxpreserveAspectRatio屬性來控制視野。

線段

SVG 可使用 <line> 元素畫出一條直線,使用只須要指定線段的起(x1, y1)止(x2, y2)點。

clipboard.png

<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg'>
  <line x1='0' y1='0' x2='100' y2='100' style='stroke:black'/>
</svg>

clipboard.png

筆畫的特性

線段能夠看做畫面上畫出來的筆畫。筆畫的尺寸、顏色和風格都會影響線段的表現。這些特性均可以在 style 屬性指定。

stroke-width

stroke-width 是設置線段的粗細,以下所示:

<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg'>
  <line x1='0' y1='0' x2='100' y2='100' style='stroke-width:10;stroke:black'/>
</svg>

clipboard.png

筆畫的顏色和透明度

能夠經過如下幾種方式指定筆畫顏色:

  • 基本顏色關鍵字: aqua、black、blue、fuchsia、gray、green 等
  • 由 6 位十六進制指定的顏色,形式爲 #rrggbb,其中 rr 表示紅色, gg 表示綠色, bb 表示藍色,它們的範圍都是 00--ff
  • 由 3 位十六進制指定的顏色,形式爲 #rgb,其中 r 表示紅色,g 表示綠色, b 表示藍色,它們的範圍都是 0-f
  • 經過 rgb() 形式指定的 rgb 顏色值,每一個值的取值範圍都是整數 0-255 或者百分比 0 - 100%
  • currentColor 關鍵字,表示當前元素應用的 CSS 屬性 color 的值。color 是用來給 HTML 的文本設置顏色的,會被子元素繼承,但對 SVG 沒有直接效果。

線段都是實線,我們也可使用 stroke-opacity 來控制線的透明度,取值範圍和 CSS 同樣 0.0-1.0,來幾個例子演示一下:

來幾個例子演示一下:

<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg'>
  <!-- 紅色 -->
  <line x1='10' y1='10' x2='50' y2='10' style='stroke-width:5;stroke:red'/>
  <!-- 談綠色 -->
  <line x1='10' y1='20' x2='50' y2='20' style='stroke-width:5;stroke:#9f9f;stroke-opacity: 0.2' />
  <!-- 橘色 -->
  <line x1='10' y1='40' x2='50' y2='40' style='stroke-width:5;stroke:rgb(255,128,64);stroke-opacity: 0.5' />
  <!-- 深紫色 -->
  <line x1='10' y1='50' x2='50' y2='50' style='stroke-width:5;stroke:rgb(60%,20%,60%);stroke-opacity: 0.8' />
</svg>

clipboard.png

若是不指定筆畫顏色的話,將看不到任何線,由於 stroke 屬性的默認值是 none

stroke-dasharray 屬性

有時我們須要點線和虛線,剛須要使用 stroke-dasharray 屬性,它的值由一列數字構成,表明線的長度和空隙的長度,數字之間用逗號或空格隔開。數字的個數應該爲偶數,但若是是奇數,則 SVG 會重複不次,讓總數爲偶數。

<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
  <!-- 9個像素的虛線,5個像素的空隙 -->
  <line x1='10' y1='10' x2='100' y2='10'
    style='stroke-dasharray:9, 5; stroke: black; stroke-width:2'
  />
  <!-- 5個像素的虛線,3個像素的空隙 ,9個像素的虛線,2個像素的空隙 -->
  <line x1='10' y1='30' x2='100' y2='30'
    style='stroke-dasharray:9, 5, 9, 2; stroke: black; stroke-width:2' />
  <!-- 複製奇數個數 -->
  <line x1='10' y1='50' x2='100' y2='50'
    style='stroke-dasharray:9, 3, 5; stroke: black; stroke-width:2' />
</svg>

clipboard.png

矩形

clipboard.png

矩形是最簡單基本形狀,只須要其左上角 xy 座標以及它的寬度(width)和高度(height),若是想要指定圓角,能夠指定 rx(x方向的圓角半徑),該最大值是矩形寬度的一半,同理,ry(y 方向的圓角半徑),該最大值是矩形高度的一半。若是隻指定了 rxry 中的一個值,則認爲它們相等,矩形內部還可使用 fill 屬性來填充顏色,默認爲黑色,用 stroke 來繪製邊框,默認透明。來幾個例子看看。

<svg width='300' height='500' xmlns='http://wwww.w3.org/2000/svg'>
  <!-- 內部填充爲黑色,不繪製邊框 -->
  <rect x='10' y='10' width='30' height='50'/>
  <!-- 內部填充爲藍色,繪製較粗,半透明紅色邊框-->
  <rect x='50' y='10' width='30' height='50'
    style='fill: #0000ff;stroke: red;stroke-width: 7; stroke-opacity: .5'/>
  <!-- rx 和 ry 相等,逐漸增大-->
  <rect x='10' y='70' rx='2' ry='2' width='20' height='40' 
    style='stroke:black; fill:none'/>ry5'
  <!-- rx 和 ry 相等,逐漸增大-->
  <rect x='50' y='70' rx='5'  width='20' height='40' 
    style='stroke:black; fill:none' />
  <!-- rx 和 ry 不相等 -->
  <rect x='10' y='130' rx='10' ry='5' width='20' height='40' style='stroke:black; fill:none' />
  <rect x='50' y='130' rx='10' ry='5' width='10' height='40' style='stroke:black; fill:none' />
</svg>

clipboard.png

圓和橢圓

clipboard.png

畫一個圓,須要使用 <circle> 元素,並指定圓心的 xy 座標(cx/cy) 以及半徑(r)。和矩形同樣,不指定 fill 和 stroke 時,圓會使用黑色填充而且沒有輪廓線。

clipboard.png

<svg width='300' height='500' xmlns='http://wwww.w3.org/2000/svg'>
  <circle cx='30' cy='30' r='20' style='stroke:black; fill:none'/>
  <circle cx='80' cy='30' r='20' style='stroke-width:5;stroke:black; fill:none' />

  <ellipse cx='30' cy='80' rx='10' ry='20'
    style='stroke:black; fill:none'
  />
  <ellipse cx='80' cy='80' rx='20' ry='10'
    style='stroke:black; fill:none'
  />
</svg>

對於橢圓來講,除了指定圓心和座標外,還須要同時指定 x 方向的半徑和 y 方向的半徑,屬性分爲是 rxry。對於圓和橢圓來講,若是省略 cx 或者 cy ,則默認爲 0,若是半徑爲 0,則不會顯示圖形,若是半徑爲負數,則會報錯。來幾個例子看看:

clipboard.png

多邊形

clipboard.png

我們可使用 <polygon> 元素繪製多邊形,使用 points 屬性指定一系列的 x/y 座標對,並用逗號或者空格分隔座標個數必須是偶數。指定座標不須要在最後指定返回起始座標, <polygon> 元素會自動回到起始座標。來幾個例子看看:

<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
  <!--平等四邊形-->
  <polygon points='15,10 55,10 45,20 5,20'
    style='fill:red; stroke: black;'
  />
  <!--五角星-->
  <polygon points='35,37.5 37.9,46.1 46.9,46.1 39.7,51.5
    42.3,60.1 35,55 27.7,60.1 30.3,51.5 23.1,46.1 32.1,46.1'
    style='fill: #ccffcc; stroke: green;'
    />
  <!--不規則圖形-->
  <polygon points='60 60, 65,72 80 60, 90,90 72,85 50,95'
    style="fill: yellow; fill-opacity:.5; stroke:black"
  />
</svg>

clipboard.png

從上面很容易看出多邊形都很容易填充,由於多邊形的各邊都沒有交叉,很容易區分出多邊形的內部區域和外部區域。可是,當多邊形彼此交叉的時候,要區分哪些區域是圖形內部並不容易。以下如融合所示,中間的區域是算內部仍是外部呢?

<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
  <polygon points='48,16 16,96 96,48 0,48 80,96'
    style='fill:none; stroke: black;'
  />
</svg>

clipboard.png

SVG有兩種判斷某個點是否在多邊形中的規則。分別對應fill-true屬性的nonezero(默認值)和evenodd。其效果圖分別以下:

<body style='padding: 100px 0 0 200px'>

<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
  <polygon points='48,16 16,96 96,48 0,48 80,96'
    style='fill-rule: nonzero; fill:yellow; stroke: black;'
  />

  <polygon points='148,16 116,96 196,48 100,48 180,96'
    style='fill-rule: evenodd; fill:red; stroke: black;' />
</svg>

clipboard.png

拆線

clipboard.png

<polyline> 元素與 <polygon> 有相同的屬性,不一樣之處在於圖形並不封閉,直接來個事例看看:

<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
  <polyline points="5,20 20,20 25,10 35,30 45,10
    55,30 65,10 74,30 80,20 95,20"
    style="stroke:black; stroke-width:3; fill:none"
  />
</svg>

clipboard.png

總結

形狀元素

線段:<line x1=" " y1=" " x2=" " y2=" " style=" "/>

矩形:<rect x=" "  y=" "  width=" "  height=" "  style=" "/>

圓角矩形:<rect x=" "  y=" "  rx=" "  ry=" "  style=" "/>

圓形:<circle cx=" "  cy=" "  r=" " style=" "/>

橢圓形:<ellipse cx=" "  cy=" "  rx=" "  ry=" "  style=" " />

多邊形:<polygon points="      "  style=" "/>

折線:<polyline points="    "  style=" "/> //注意需把fill設成none

SVG有兩種判斷某個點是否在多邊形中的規則。分別對應fill-true屬性的nonezero(默認值)和evenodd。其效果圖分別以下:

clipboard.png

筆畫特性:

屬性
stoke 筆畫顏色,默認爲none
stroke-opacity 筆畫透明度,默認爲1.0(徹底不透明),值範圍:0.0~1.0
stroke-dasharray 用一系列數字指定虛線和間隙的長度,如:stroke-dasharray:5,10,5,20
stroke-linecap 線頭尾的形狀:butt(默認)、round、square
stroke-linejoin 圖形的棱角或一系列連線的形狀:miter(尖的,默認值)、round(圓的)、bevel(平的)
stroke-miterlimit 相交處顯示寬度與線寬的最大比例,默認爲4

填充顏色

屬性
fill 指定填充顏色,默認值爲 black
fill-opacity 從 0.0 到 1.0 的數字, 0.0 表示徹底透明, 1.0(默認值) 表示徹底不透明
fill-rule 屬性值爲 nonzero (默認值) 或 evenodd。

在 SVG 中使用樣式

在 SVG 的使用樣式中 CSS 很類似,主要有 4 種,分別以下:

  • 內聯樣式
  • 內部樣式表
  • 外部樣式表
  • 表現屬性

內聯樣式

用法跟 css 同樣,以下所示:

<line style="fill:yellow;stroke:blue;stroke-width=4" x1="10" y1="10" x2="100" y2="100"/>*

內部樣式表

用法也跟 css 的類名同樣,以下所示:

.linestyle{
stroke:red;
stroke-width:2;
}
// 那麼在使用標籤時,指定此樣式便可:
<line class="linestyle" x1="10" y1="10" x2="100" y2="100"/>

外部樣式表

跟 CSS 用法同樣,把樣式寫在另外文件中,而後導入使用。

表現屬性

我們可能經過 style 屬性修改樣式,固然 style 裏面的屬性值,能夠單獨寫,這種也叫表現屬性:

<circle cx='10' cy='10' r='5'
  fill='red' stroke='black' stroke-width='2'/>

分組與引用對象

雖然能夠將全部的繪圖當作是由一系列幾乎同樣的形狀和線條組成的,但一般我們仍是認爲大多數非抽象的藝術做品是由一系列命名對象組成的,而這些對象由形狀和線條組合而成。SVG 提供了一些元素,容許我們對元素進行這樣的分組,從而使文檔更加結構化以及更易理解。

<g> 元素

1)<g>元素會將全部子元素做爲一個組合,一般還有一個惟一的id做爲名稱;
2)每一個組合還能夠擁有本身的<title><desc>來供基於文本的xml應用程序識別或者爲視障用戶提供更好的可訪問性;
3)閱讀器會讀取<title><desc>元素的內容。鼠標懸停或者輕觸組合內的圖形時,會顯示<title>元素內容的提示框。
4)<g>元素能夠組合元素並能夠提供一些註釋,組合還能夠比較嵌套;

在起始 <g> 標籤中指定的全部樣式會應用於組合內的全部子元素,以下面示例所示,我們能夠不用複製每一個元素上的 style='fill:none; stroke:black;'

<svg width='240' height='240' xmlns='http://wwww.w3.org/2000/svg'>
  <title>歡樂一家人</title>
  <desc>一家人在一塊兒就是簡單幸福的了</desc>

  <g id='house' style='fill:none; stroke:black'>
    <desc>房子</desc>
    <rect x='6' y='50' width='60' height='60'/>
    <polyline points='6 50, 36 9, 66 50' />
    <polyline points='36 110, 36 80, 50 80, 50 110' />
  </g>

  <g id='man' style='fill:none; stroke:green'>
    <desc>男人</desc>
    <circle cx='85' cy='56' r='10'/>
    <line x1='85' y1='66' x2='85' y2='80'/>
    <polyline points='76 104, 85 80, 94 104'/>
    <polyline points='76 70, 85 76, 94 70'/>
  </g>

  <g id='woman' style='fill:none; stroke:red'>
    <desc>女人</desc>
    <circle cx='110' cy='56' r='10'/>
    <polyline points='110 66, 110 80, 100 90, 120 90, 110 80'/>
    <line x1='104' y1='104' x2='108' y2='90'/>
    <line x1='112' y1='90' x2='116' y2='104'/>
    <polyline points='101 70, 110 76, 119 80'/>
  </g>
 </svg>

clipboard.png

<use> 元素

1)複雜的圖形中常常會出現重複元素,svg 使用<use>元素爲定義在<g>元素內的組合或者任意獨立圖形元素提供了相似複雜黏貼的能力;
2)定義了一組<g>圖形對象後,使用<use>標籤再次顯示它們。要指定想要的重用的組合就給xlink:href屬性指定URI便可,同時還要指定xy的位置以表示組合應該移動到的位置。
3)<use>元素並不限制只使用在同一個文件內的對象,還能夠指定任意有效的文件或者URI.

所以爲了建立另外一個上面的房子和一組小人,只要把下面的代碼入 <svg> 元素裏面便可。

<use xlink:href='#house' x='70' y='100'/>
<use xlink:href='#woman' x='-80' y='100'/>
<use xlink:href='#man' x='-30' y='100'/>

clipboard.png

<defs>元素

上面例子有幾個缺點:

  • 複用 manwoman 組合時,須要知道原始圖像中這些圖形的位置,並以此位置做爲利用的基礎,而不是使用諸如 0 這樣的簡單數字
  • 房子的填充和筆畫顏色由原始圖形創建,而且不能經過 <use> 元素覆蓋,這說明我們不能構造一行彩色的房子。
  • 文檔中會畫出全部的三個元素 woman,man 和 house,並不能將它們單獨 '存儲' 下來,而後只繪製一排房子或者只繪製一組人。

<defs> 元素能夠解決這些問題

1)SVG規範推薦咱們將全部想要複用的對象放置在元素內,這樣SVG閱讀器進入流式環境中就能更輕鬆地處理數據。
2)因爲組合在<defs>元素內,它們不會馬上繪製到屏幕上,而是做爲"模板"供其餘地方使用。

<svg width='240' height='240' viewBox='0 0 240 240' xmlns='http://wwww.w3.org/2000/svg'>
  <title>歡樂一家人</title>
  <desc>一家人在一塊兒就是簡單幸福的了</desc>
  
  <defs>
    <g id='house' style='stroke:black'>
      <desc>房子</desc>
      <rect x='0' y='41' width='60' height='60' />
      <polyline points='0 41, 30 0, 60 41' />
      <polyline points='30 110, 30 71, 44 71, 44 101' />
    </g>
    
    <g id='man' style='fill:none; stroke:green'>
      <desc>男人</desc>
      <circle cx='10' cy='10' r='10' />
      <line x1='10' y1='20' x2='10' y2='44' />
      <polyline points='1 58, 10 44, 19 58' />
      <polyline points='1 24, 10 30, 19 24' />
    </g>
    
    <g id='woman' style='fill:none; stroke:red'>
      <desc>女人</desc>
      <circle cx='10' cy='10' r='10' />
      <polyline points='10 20, 10 34, 0 44, 20 44, 10 34' />
      <line x1='4' y1='58' x2='8' y2='44' />
      <line x1='12' y1='44' x2='16' y2='58' />
      <polyline points='1 24, 10 30, 19 24' />
    </g>

    <g id='couple'>
      <desc>夫妻</desc>
      <use xlink:href='#man' x='0' y='0'/>
      <use xlink:href='#woman' x='25' y='0'/>
    </g>
  </defs>
  <use xlink:href='#house' x='0' y='0' style='fill:#cfc'/>
  <use xlink:href='#couple' x='70' y='40'/>

  <use xlink:href='#house' x='120' y='0' style='fill:#99f' />
  <use xlink:href='#couple' x='190' y='40' />
</svg>

clipboard.png

<symbol>元素

<symbol>做爲模板,同<defs>同樣,內部的全部元素都不會展示在畫布上,所以我們無需把它放在 <defs> 規範內。然而,我們仍是習慣將它放到 <defs> 中,由於 symbol 也是我們定義的供後續使用的元素。

<svg width='240' height='240' viewBox='0 0 240 240' xmlns='http://wwww.w3.org/2000/svg'>
  <defs>
    <symbol id="circle" viewBox="0 0 100 100" preserveAspectRatio="xMinYMin meet">
      <circle cx="50" cy="50" r="50"></circle>
    </symbol>
    <symbol id="triangle" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax slice">
      <polygon points="0 0, 100 0, 50 100"></polygon>
    </symbol>
  </defs>
  <g stroke="grey" fill="none">
    <rect x="0" y="0" width="50" height="100"></rect>
    <rect x="100" y="0" width="50" height="100"></rect>
  </g>
  <use xlink:href="#circle" width="50" height="100" fill="red"></use>
  <use xlink:href="#triangle" width="50" height="100" fill="red" x="100"></use>
</svg>

clipboard.png

image 元素

<image>顧名思義裏面放圖片的,至於說是矢量圖(vector)仍是位圖(raster),都成,用起來也方便:

<svg width='310' height='310' viewBox='0 0 310 310' xmlns='http://wwww.w3.org/2000/svg'>
  <ellipse cx='154' cy='154' rx='150' ry='120' style='fill: #999'/>
  <ellipse cx='152' cy='152' rx='150' ry='120' style='fill: #999' />

  <image xlink:href='3.jpg' x='72' y='92'
    width='160' height='120'
  />
</svg>

clipboard.png

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

參考:

騰訊課堂《走入SVG》
慕課網《走進SVG》
<SVG 精髓>

交流(歡迎加入羣,羣工做日都會發紅包,互動討論技術)

阿里雲最近在作活動,低至2折,有興趣能夠看看:https://promotion.aliyun.com/...

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

由於篇幅的限制,今天的分享只到這裏。若是你們想了解更多的內容的話,能夠去掃一掃每篇文章最下面的二維碼,而後關注我們的微信公衆號,瞭解更多的資訊和有價值的內容。

clipboard.png

每次整理文章,通常都到2點才睡覺,一週4次左右,挺苦的,還望支持,給點鼓勵

clipboard.png

相關文章
相關標籤/搜索