第一次注意到 SVG,是設計稿中使用到 Iconify Design 的 icon。在操作面板調整 icon 的顏色、大小的時候,發現 SVG 碼會有對應的變化。
一開始只是意識到 能直接在 HTML 複製貼上、能調整 fill 屬性改變顏色。沒想到,之後工作時能用 SVG 解決了許多難題。
今天先來了解 SVG 是什麼,以及它有哪些設定吧!
SVG,全名 Scalable Vector Graphics 可縮放向量圖形。是一種「用來畫向量圖」的 XML 規範。它繼承了 XML 的語法結構,並定義了一套特定標籤(例如圓形就是 <circle cx="6" cy="6" r="5" />)。透過標籤與屬性的設定,讓瀏覽器知道怎麼畫出對應的圖案。
來看個簡單的範例。下面這段 code 在瀏覽器會被渲染成一個「在 12px × 12px 的畫布中畫出紅色圓形」。也可以到 iconify 內手動操作面板看看。
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
<circle cx="6" cy="6" r="5" fill="#e74747" stroke="#e74747" />
</svg>
為什麼要用 SVG 呢?全用 PNG 不就好了嗎?用 SVG 處理向量圖,除了檔案大小會比 .png 小很多外,還有很多超讚的地方!
這三種方式都能處理圖形,但各自擅長的地方不太一樣。
| SVG | PNG | Canvas | |
|---|---|---|---|
| 圖形類型 | 向量 | 點陣 | 點陣(由 JS 繪製) |
| 縮放 | 不失真 | 放大會模糊 | 放大會模糊,需自行處理高解析度螢幕 |
| 內部元素 | 每個圖形都是 DOM 節點 | 一整張圖,無法個別操作 | 畫完只剩像素,沒有個別元素 |
| CSS 樣式 | 可以 | 無法改內部顏色 | 無法 |
| 事件監聽 | 可綁定在單一圖形上 | 只能綁在整張圖 | 只能綁在整個畫布,需自行判斷點到哪個圖形 |
| 大量物件的效能 | 節點多了會卡頓 | 不受影響 | 表現最好 |
| 適合情境 | icon、Logo、圖表 | 照片、複雜圖像 | 遊戲、網頁白板 |
<svg>一個 SVG 從會 <svg> 標籤開始,需要設定:
width 和 height 定義了 SVG 容器寬度與高度,決定佔用多大空間。viewBox 定義了 SVG 內部元素繪製時的座標系與邊界。能確保圖形縮放後保持比例,不失真。由左到右的四個數字分別是:
min-x:相對畫布左上角的起始 x 座標min-y:相對畫布左上角的起始 y 座標width:畫布(可視)寬度height:畫布(可視)高度xmlns="http://www.w3.org/2000/svg"宣告這是 XML 命名空間。我自己常用 SVG 處理 icon 跟向量圖案,所以比較常看到的是 <path>、<circle>與 <text>
| 標籤 | 說明 | 主要屬性 | 範例 |
|---|---|---|---|
圓形 <circle> |
以圓心和半徑畫出正圓 | cx、cy(圓心座標)、r(半徑) |
<circle cx="6" cy="6" r="5" /> |
橢圓形 <ellipse> |
與圓形類似,但水平、垂直半徑可以不同 | cx、cy、rx(水平半徑)、ry(垂直半徑) |
<ellipse cx="10" cy="6" rx="8" ry="5" /> |
矩形 <rect> |
畫出矩形,加上 rx、ry 可做出圓角 |
x、y(左上角座標)、width、height、rx、ry |
<rect x="1" y="1" width="10" height="8" rx="2" /> |
線條 <line> |
連接兩個點的直線 | x1、y1(起點)、x2、y2(終點) |
<line x1="0" y1="0" x2="10" y2="10" stroke="black" /> |
折線 <polyline> |
連接多個點的線,起點與終點不會自動連起來 | points(一連串座標) |
<polyline points="0,0 5,8 10,2" fill="none" stroke="black" /> |
多邊形 <polygon> |
連接多個點並自動封閉成一個圖形 | points(一連串座標) |
<polygon points="6,1 11,11 1,11" /> |
路徑 <path> |
最靈活的標籤,能用指令畫出直線、曲線與任意形狀,icon 大多是用它畫的 | d(路徑指令) |
<path d="M0 0h12v12H0z" /> |
文字 <text> |
在指定位置顯示文字 | x、y(文字基準線起點)、font-size 等 |
<text x="0" y="10">Hello</text> |
| 屬性 | 說明 | 範例 |
|---|---|---|
fill |
圖形的填充顏色。沒設定時預設為黑色,設成 none 則不填色 |
fill="#e74747" |
stroke |
圖形的線條 / 邊框顏色。沒設定時預設為無 | stroke="#e74747" |
stroke-width |
圖形的線條 / 邊框粗細,預設為 1 | stroke-width="2" |
color |
設定 currentColor 的值,搭配 fill="currentColor" 或 stroke="currentColor" 使用,可以讓圖形跟隨外層文字顏色變化 |
color="red" 或 CSS color: red |
opacity |
整體透明度,範圍 0 到 1 | opacity="0.5" |
另外,SVG 標籤也能接受 class、style 與 id 屬性。
.
.
.
簡介到這邊告一段落。
明天,來實際應用看看 SVG 能做到什麼事情吧!
在收集資料階段,找到許多有趣的範例,像是這個聖誕節倒數月曆。除此之外,還有許多 D3.js 函式庫的教學文,實在大開眼界。尤其是 D3.js 能應用的情境非常廣。感覺能滿足之前專案的需求,有種相見恨晚的感覺。