[譯] 深刻淺出 SVG

深刻淺出 SVG

SVG 是優秀且使人難以置信的強大圖像格式。本教程經過簡單地解釋全部須要瞭解的知識,爲您提供 SVG 的概述。css

介紹

儘管在 21 世紀初被標準化了,SVG(Scalable Vector Graphics 的縮寫)是近年來的一個熱門話題。html

SVG 已經被糟糕的瀏覽器支持(尤爲是 IE)懲罰了好多年。前端

我發現這話源自一本 2011 的書:在撰寫本文時,只有在最新的瀏覽器中才能將 SVG 直接嵌入到 HTML 中工做。7 年過去了,這句話如今已是過去式了,咱們能夠很安全地使用 SVG 圖像。android

如今咱們能夠安全地使用 SVG 圖像,除非您有不少用戶使用 IE8 以及更低版本,或者使用較舊的 Android 設備。這種狀況下,依然存在着備選方案。ios

SVG 支持的瀏覽器

SVG 成功的一部分是因爲咱們必須支持各類不一樣分辨率和尺寸的屏幕顯示。SVG 能完美解決這個問題。git

同時,Flash 在過去幾年的迅速衰退致使你們對 SVG 產生了興趣。這對於 Flash 過去所作的許多事情都是很是重要的。github

SVG 是一種 vector 圖像文件格式。這使得它們與其餘圖像格式(如 PNG、GIF 或 JPG)有很大的不一樣,後者是光柵圖像文件格式。web

SVG 的優點

因爲 SVG 圖像是矢量圖像,能夠無限縮放,並且在圖像質量降低方面沒有任何問題。爲何會這樣呢?由於 SVG 圖像是使用 XML 標記構建的,瀏覽器經過繪製每一個點和線來打印它們,而不是用預約義的像素填充某些空間。這確保 SVG 圖像能夠適應不一樣的屏幕大小和分辨率,即便是那些還沒有發明的。後端

因爲是在 XML 中定義的,SVG 圖像比 JPG 或 PNG 圖像更靈活,並且咱們可使用 CSS 和 JavaScript 與它們進行交互。SVG 圖像設置能夠包含 CSS 和 JavaScript。api

SVG 能夠渲染比其餘格式小得多的矢量風格圖像,主要用於標識和插圖。另外一個巨大的用例是圖標。曾經是圖標字體域,好比 FontAwesome,如今的設計師更喜歡使用 SVG 圖像,由於它更小,而且容許使用多色圖標。

SVG 在動畫方面很簡單,這是一個很是酷的話題。

SVG 提供了一些圖像編輯效果,好比屏蔽和剪裁、應用過濾器等等。

SVG 只是文本,所以可使用 GZip 對其進行有效壓縮。

您的第一個 SVG 圖像

SVG 圖像使用 XML 定義,這意味着若是您精通 HTML,SVG 看起來會很是熟悉,除了在 SVG 中有標籤適合文檔構建(如 particlefooteraside)咱們還有矢量圖的構建塊: pathrectline 等等。

這是一個 SVG 圖像示例:

<svg width="10" height="10">
  <rect x="0" y="0" width="10" height="10" fill="blue" />
</svg>
複製代碼

注意它很是容易閱讀和理解圖像的樣子:它是一個 10 x 10 像素的簡單藍色矩形(默認單元)。

大多狀況下,您沒必要編寫 SVG 代碼,由於您可使用 Sketch 或 Figma 等工具或任何其餘矢量圖形工具來建立圖像,並將其導出爲 SVG。

SVG 的當前版本是 1.1, SVG 2.0 正在研發。

使用 SVG

瀏覽器能夠經過將它們包含在一個 img 標籤中來顯示 SVG 圖像:

<img src="image.svg" alt="My SVG image" />
複製代碼

就像其餘基於像素的圖像格式同樣:

<img src="image.png" alt="My PNG image" />
<img src="image.jpg" alt="My JPG image" />
<img src="image.gif" alt="My GIF image" />
<img src="image.webp" alt="My WebP image" />
複製代碼

此外,SVG 很是獨特,它們能夠直接包含在 HTML 頁面中:

<!DOCTYPE html>
<html>
  <head>
    <title>A page</title>
  </head>
  <body>
    <svg width="10" height="10">
      <rect x="0" y="0" width="10" height="10" fill="blue" />
    </svg>
  </body>
</html>
複製代碼

請注意 HTML5 和 XHTML 對於內聯 SVG 圖像須要不一樣的語法。幸運的是,XHTML已是過去的事情了,由於它過於繁雜,可是若是您仍然須要處理 XHTML 頁面,就值得去了解它。

在 HTLM 中內聯 SVG 的功能使該格式成爲場景中的 unicorn,由於其餘圖像不能這樣作,必須爲每一個圖像打開一個單獨的請求來獲取該格式。

SVG 元素

在上面的示例中,您看到了 rect 元素的用法。SVG 有許多不一樣的元素。

最經常使用的是

  • text: 建立一個 text 元素
  • circle: 建立一個圓
  • rect: 建立一個矩形
  • line: 建立一條線
  • path: 在兩點之間建立一條路徑
  • textPath: 在兩點之間建立一條路徑,並建立一個連接文本元素
  • polygon: 容許建立任意類型的多邊形
  • g: 單獨的元素

座標從繪圖區域左上角的 0,0 開始,並 從左到右表示 x, 從上到下表示 y

您看到的圖像反映了上面所示的代碼。使用瀏覽器 DevTools,您能夠檢查和更改它們。

text

text 元素添加文本。可使用鼠標選擇文本。xy 定義文本的起始點。

<svg>
  <text x="5" y="30">A nice rectangle</text>
</svg>
複製代碼
漂亮的長方形

circle

定義圓。 cxcy 是中心座標,r 是半徑。 fill 是一個經常使用屬性,表示圖形顏色。

<svg>
  <circle cx="50" cy="50" r="50" fill="#529fca" />
</svg>
複製代碼

rect

定義矩形。 xy 是起始座標,widthheight 是自解釋的。

<svg>
  <rect x="0" y="0" width="100" height="100" fill="#529fca" />
</svg>
複製代碼

line

x1y1 定義起始座標。x2y2 定義結束座標。stroke 是一個經常使用屬性,表示線條顏色。

<svg>
  <line x1="0" y1="0" x2="100" y2="100" stroke="#529fca" />
</svg>
複製代碼

path

路徑是一系列的直線和曲線。它是全部 SVG 繪製工具中最強大的,所以也是最複雜的。

d 包含方向命令。這些命令以命令名和一組座標開始:

  • M 表示移動,它接受一組 x,y 座標
  • L 表示直線將繪製到它接受一組 x,y
  • H 是一條水平線,它只接受 x 座標
  • V 是一條垂直線,它只接受 y 座標
  • Z 表示關閉路徑,並將其放回起始位置
  • A 表示 Arch,它本身須要一個完整的教程
  • Q 是一條二次 Bezier 曲線,一樣,它本身也須要一個完整的教程
<svg height="300" width="300">
  <path d="M 100 100 L 200 200 H 10 V 40 H 70"
        fill="#59fa81" stroke="#d85b49" stroke-width="3" />
</svg>
複製代碼

textPath

沿路徑元素的形狀添加文本。

Wow such a nice SVG tut

polygon

使用 polygon 繪製任意多邊形。 points 表明一組 x,y 座標多邊形應該連接:

<svg>
  <polygon points="9.9, 1.1, 3.3, 21.78, 19.8, 8.58, 0, 8.58, 16.5, 21.78" />
</svg>
複製代碼

g

使用 g 元素,您能夠對多個元素進行分組:

<svg width="200" height="200">
  <rect x="0" y="0" width="100" height="100" fill="#529fca" />
  <g id="my-group">
    <rect x="0" y="100" width="100" height="100" fill="#59fa81" />
    <rect x="100" y="0" width="100" height="100" fill="#59fa81" />
  </g>
</svg>
複製代碼

SVG viewport 和 viewBox

SVG 相對於其容器的大小由 svg 元素的 widthheight 屬性設置。這些單位默認爲像素,但您可使用任何其餘經常使用單位,如 %em。這是 viewport

一般 「container」 指的是瀏覽器窗口,但 svg 元素能夠包含其餘 svg 元素,在這種狀況下,容器是父元素 svg

一個重要的屬性是 viewBox。它容許您在 SVG 畫布中定義一個新的座標系統。

假設在 200x200px SVG 中有一個簡單的圓:

<svg width="200" height="200">
  <circle cx="100" cy="100" r="100" fill="#529fca" />
</svg>
複製代碼

經過指定 viewBox ,您能夠選擇 只顯示此 SVG 的一部分。例如,您能夠從 0,0 點開始,只顯示一個 100 x 100 px 畫布:

<svg width="200" height="200" viewBox="0 0 100 100">
  <circle cx="100" cy="100" r="100" fill="#529fca" />
</svg>
複製代碼

從 100,100 開始,您會看到另外一部分,圓圈的右下角:

<svg width="200" height="200" viewBox="100 100 100 100">
  <circle cx="100" cy="100" r="100" fill="#529fca" />
</svg>
複製代碼

一個很好的可視化方法是想象 Google Maps 是一個巨大的 SVG 圖像,而您的瀏覽器是一個和窗口大小同樣大的視圖框。當您移動時,Viewbox 會更改它的起始點(x,y)座標,而且當您調整窗口的大小時,會更改 Viewbox 的寬度和高度。

在 Web 網頁中插入 SVG

將 SVG 添加到網頁中有多種方法。

最多見的是:

  • 帶有 img 標籤
  • 帶有 CSS background-image 屬性
  • 在 HTML 中內聯
  • 帶有 objectiframeembed 標籤

在 Glitch 上能夠查看這些示例 flavio-svg-loading-ways.glitch.me/

帶有 img 標籤

<img src="flag.svg" alt="Flag" />
複製代碼

帶有 css background-image 屬性

<style>
.svg-background {
  background-image: url(flag.svg);
  height: 200px;
  width: 300px;
}
</style>
<div class="svg-background"></div>
複製代碼

在 HTML 中內聯

<svg width="300" height="200" viewBox="0 0 300 200"
    version="1.1" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Italian Flag</title>
  <desc>By Flavio Copes https://flaviocopes.com</desc>
  <g id="flag">
      <rect fill="green" x="0" y="0" width="100" height="200"></rect>
      <rect fill="white" x="100" y="0" width="100" height="200"></rect>
      <rect fill="red" x="200" y="0" width="100" height="200"></rect>
  </g>
</svg>
複製代碼

帶有 objectiframeembed 標籤

<object data="flag.svg" type="image/svg+xml"></object>

<iframe src="flag.svg" frameborder="0"></iframe>

<embed src="flag.svg" type="" />
複製代碼

使用 embed,您可使用如下命令從父文檔獲取 SVG 文檔

document.getElementById('my-svg-embed').getSVGDocument()
複製代碼

在 SVG 內部,您能夠經過如下方式引用父文檔:

window.parent.document
複製代碼

使用數據 URL 內聯 SVG

您可使用以上任何示例結合 Data URLs 將 SVG 內聯到 HTML 中:

<img src="data:image/svg+xml;<DATA>" alt="Flag" />

<object data="data:image/svg+xml;<DATA>" type="image/svg+xml"></object>

<iframe data="data:image/svg+xml;<DATA>" frameborder="0"></iframe>
複製代碼

在 CSS 中也是:

.svg-background {
  background-image: url("data:image/svg+xml;<DATA>");
}
複製代碼

只需使用適當的Data URL 更改<DATA>

樣式元素

任何 SVG 元素均可以接受 style 屬性,就像 HTML標籤同樣。並不是全部的 CSS 屬性都能像您預期的那樣工做。例如,要更改文本元素的顏色,請使用 fill 而不是 color

<svg>
  <text x="5" y="30" style="fill: green">A nice text</text>
</svg>

<svg>
  <text x="5" y="70" style="fill: green; font-family: Courier New">
    A nice text
  </text>
</svg>
複製代碼

您也可使用 fill 做爲元素屬性,正如您在前面看到的那樣:

<svg>
  <text x="5" y="70" fill="green">A nice text</text>
</svg>
複製代碼

其餘公共屬性包括

  • fill-opacity,背景顏色不透明度
  • stroke,定義邊框顏色
  • stroke-width,設置邊框寬度

CSS 能夠針對 SVG 元素,就像您以 HTML 標籤爲目標同樣:

rect {
  fill: red;
}
circle {
  fill: blue;
}
複製代碼

使用 CSS 或 JavaSCript 與 SVG 交互

SVG 圖像可使用 CSS 進行樣式化,或者使用 JavaScript 編寫腳本,這種狀況下:

  • 當 SVG 在 HTML 中內聯
  • 經過 objectembediframe 標籤加載圖像時

可是 (⚠️ 取決於瀏覽器實現) 它們必須從相同的域(和協議)加載,這是同源策略所致使的。 iframe 須要顯式定義的尺寸,不然內容將被裁剪,同時調整 objectembed 尺寸以適應其內容。.

若是 SVG 是使用 img 標籤加載的,或者使用 CSS 做爲背景,則與源無關:

  • CSS 和 JavaScript 不能與之進行交互
  • SVG 中包含的 JavaScript 被禁用
  • 沒法從外部加載資源(如圖像、樣式表、腳本、字體)

細節


特性 SVG 內聯 object/embed/iframe img
能夠與用戶交互
支持動畫
能夠運行 JavaScript 腳本 👎🏼
能夠從外部編寫腳本 👎🏼 👎🏼

內聯 SVG 圖像無疑是最強大和最靈活的,它是使用 SVG 執行某些操做的惟一方法。

若是您想要 SVG 與您的腳本進行任何交互,它必須之內聯的方式加載到 HTML中

若是您不須要與 SVG 交互,只需在頁面中顯示它,將 SVG 加載至 imgobject 或者 embed 中便可,若是您在不一樣的頁面中重用 SVG 圖像,或者 SVG 圖像的大小至關大,那麼加載 SVG 就特別方便。

CSS 嵌入 SVG

將 CSS 加至 CDATA:

<svg>
  <style>
    <![CDATA[
      #my-rect { fill: blue; }
    ]]>
  </style>
  <rect id="my-rect" x="0" y="0" width="10" height="10" />
</svg>
複製代碼

SVG 文件還能夠包括外部樣式表

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
     width=".." height=".." viewBox="..">
  <rect id="my-rect" x="0" y="0" width="10" height="10" />
</svg>
複製代碼

JavaScript 嵌入 SVG

你能夠將 JavaScript 放在第一個位置上,幷包裝在一個 load 事件中,以便在頁面徹底加載並在 DOM 中插入 SVG 時執行它:

<svg>
  <script>
    <![CDATA[
      window.addEventListener("load", () => {
        //...
      }, false)
    ]]>
  </script>
  <rect x="0" y="0" width="10" height="10" fill="blue" />
</svg>
複製代碼

或者若是您將 JS 放在其餘 SVG 代碼的末尾,能夠避免添加事件監聽,確保當 SVG 出如今頁面時 JavaSCript 會執行。

<svg>
  <rect x="0" y="0" width="10" height="10" fill="blue" />
  <script>
    <![CDATA[
      //...
    ]]>
  </script>
</svg>
複製代碼

與 HTML 元素同樣,SVG 元素也能夠有 idclass 屬性,所以咱們可使用 Selectors API 來引用它們:

<svg>
  <rect x="0" y="0" width="10" height="10" fill="blue"
        id="my-rect" class="a-rect" />
  <script>
    <![CDATA[
      console.log(document.getElementsByTagName('rect'))
      console.log(document.getElementById('my-rect'))
      console.log(document.querySelector('.a-rect'))
      console.log(document.querySelectorAll('.a-rect'))
    ]]>
  </script>
</svg>
複製代碼

請查看此故障 flaviocopes-svg-script.glitch.me/ 以得到功能性提示。

SVG 外部的 JavaScript

若是能夠與 SVG 交互(SVG 在 HTML 中是內聯的),則可使用 JavaScript 更改任何 SVG 屬性,例如:

document.getElementById("my-svg-rect").setAttribute("fill", "black")
複製代碼

或者真正地作任何您想要的 DOM 操做。

SVG 外部的 CSS

您可使用 CSS 更改 SVG 圖像的任何樣式。

SVG 屬性能夠很容易地在 CSS中 被覆蓋,而且它們比 CSS 具備更低的優先級。它們的行爲不像具備更高優先級的內聯 CSS。

<style>
  #my-rect {
    fill: red
  }
</style>
<svg>
  <rect x="0" y="0" width="10" height="10" fill="blue"
        id="my-rect" />
</svg>
複製代碼

SVG vs Canvas API

Canvas API 是 Web 平臺一個很好的補充,它有相似於 SVG 的瀏覽器支持。與 SVG 主要的(也是最大的)不一樣之處是:畫布不是基於矢量的,而是基於像素的,因此

  • 它具備與基於像素的 png、jpg 和 gif 圖像格式相同的縮放問題。
  • 這使得不可能像使用 SVG 那樣使用 CSS 或 JavaScropt 編輯畫布圖像。

SVG 符號

符號使您能夠定義一次SVG圖像,並在多個地方重用它。若是您須要重用一個圖像,這是一個很大的幫助,可能只是改變一點它的一些屬性。

您能夠經過添加一個 symbol 元素並分配一個 id 屬性來完成此操做:

<svg class="hidden">
  <symbol id="rectangle" viewBox="0 0 20 20">
    <rect x="0" y="0" width="300" height="300" fill="rgb(255,159,0)" />
  </symbol>
</svg>
複製代碼
<svg>
  <use xlink:href="#rectangle" href="#rectangle" />
</svg>

<svg>
  <use xlink:href="#rectangle" href="#rectangle" />
</svg>
複製代碼

(xlink:href 用於 Safari 支持,即便它是一個已廢棄的屬性)

這讓咱們能開始瞭解 SVG 的強大功能。

若是您但願對這兩個矩形使用不一樣的樣式,例如,對每一個矩形使用不一樣的顏色?您可使用CSS 變量.

<svg class="hidden">
  <symbol id="rectangle" viewBox="0 0 20 20">
    <rect x="0" y="0" width="300" height="300" fill="var(--color)" />
  </symbol>
</svg>
複製代碼
<svg class="blue">
  <use xlink:href="#rectangle" href="#rectangle" />
</svg>

<svg class="red">
  <use xlink:href="#rectangle" href="#rectangle" />
</svg>

<style>
svg.red {
  --color: red;
}
svg.blue {
  --color: blue;
}
</style>
複製代碼

查看 SVG 符號--個人 Glitch playground

驗證 SVG

SVG 文件是 XML,能夠用無效的格式編寫,有些服務或應用程序可能不接受無效的 SVG 文件。

SVG 可使用 W3C Validator驗證。

我應該包含 xmlns 屬性麼?

有時 SVG 別定義爲

<svg>
  ...
</svg>
複製代碼

有時定義爲

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>
複製代碼

第二個表單是 XHTML。它能夠與 HTML5 一塊兒使用(文檔具備 <!DOCTYPE html>),但在本例中,第一種形式更簡單。

我應該擔憂瀏覽器支持問題麼?

在 2018 版本中,絕大多數用戶的瀏覽器都支持 SVG。.

您仍然可使用諸如 Modernizr 這樣的庫來檢查缺乏的支持,並提供一個後備:

if (!Modernizr.svg) {
  $(".my-svg").attr("src", "images/logo.png");
}
複製代碼

掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索