2015-06-10

svg 簡單筆記

svg 全名 Scalable Vector Graphics ( 可縮放向量圖形), 是一個很好用又有趣的圖形檔案格式。 svg 是向量圖形,可以放很大也不失真; 可以直接寫 svg 來產生圖形,也可以直接把 svg 原始碼嵌入 html 。

之前在研究寫程式畫公車路線圖時,研究了不少 svg 原始碼的寫法, 趁現在還有點記憶趕快整理一下,一些我覺得比較好用我也比較常用的語法。


1. 開頭、結尾 <svg>

svg 檔案以這兩句作為開頭、結尾。


<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

.........

</svg>

其中 width="400" height="300" 定義 svg 圖形大小, 稱為 viewport ,數字後可以加長度單位,也可以是小數。 我覺得不加單位似乎比較方便,也和座標單位一致。如果圖形超出座標 400,300 , 超出部分就會被遮住顯示不到,所以我都是看要畫多大的圖來決定 width 和 height 。

至於座標,則是以左上角為原點,向右為 x 軸、向下為 y 軸,如上圖。

另外也可以再加上 viewBox= 的屬性來調整大小, 我沒深入研究其中的關係也沒用過 viewBox ,不過找到 這網站 分析滿清楚的。

之前試過 xmlns= 這行不加就沒辦法顯示圖形, xmlns:xlink= 這行不加有的圖形 (包括含有 <defs> 元素的) 會無法顯示。

2. 畫線 <line>、<path>、<polyline>

<line> 元素很單純,就是指定兩個座標點來畫出一條線段, 詳細可參考 教學一 教學二

<line x1="0" y1="0" x2="20" y2="30" style="stroke:rgb(255,0,0);stroke-width:3" />

不過通常要畫的線應該都不只兩個節點,似乎不是很實用。 值得注意的是後面的 style="stroke:rgb(255,0,0);stroke-width:3" 也可以改寫成 stroke="rgb(255,0,0)" stroke-width="3"

stroke 代表線條顏色,stroke-width 代表線條寬度。

另外顏色的表示可以用 rgb(255,0,0) ,也可以直接寫 red , 此外還有更多的 顏色名稱


<path> 元素則比較複雜, 可以畫出直線曲線和多邊形,座標之間用英文字母表示出如何從前一個點移動到下一個點, 其中大小寫字母又分別代表絕對座標或相對前一點的座標,詳細可參考 教學一 教學二

<path d="M 100 100 L 300 100 L 200 300 z" fill="red" stroke="blue" stroke-width="3" />

其中 fill 代表多邊形內部的塗色,一樣也有 stroke 和 stroke-width 。 另外同一組座標之間可以用空格或逗點分開,100 100 或是 100,100。 雖然功能很多,但是似乎太複雜了一點。


<polyline> 比起 <path>單純一點, 就直接把給定的座標點連起來,如果要表示成多邊形, 只要指定最後一點為第一點就好,詳細可參考 教學一 教學二

<polyline points="20,100 40,60 70,80 100,20" fill="none" stroke="black"/>

一樣有 fill 、 stroke 和 stroke-width 的屬性, stroke-width 不指定的話預設就是1; fill 不指定的話預設是 black ,所以如果要畫的圖形只是一條線, 就要加上 fill="none",不然他會自動將把頭尾連起來的內部塗上黑色; stroke 不指定的話預設是 white。

3. 形狀 <polygon>、<rect>、<circle>、<ellipse>

可畫出多邊形的元素,<path> 、 <polyline> 和 <polygon> 都行, 其中 <polygon> 和 <polyline> 的差異就是 <polygon> 會自動把頭尾連起來而 <polyline> 不會, 詳細可參考 教學一 教學二

<polygon points="20,100 40,60 70,80 100,20" fill="red" stroke="black" stroke-width="3"/>

一樣有 fill 、 stroke 和 stroke-width 的屬性,規則和 <polyline> 一樣。 要畫多邊形的話,我會選擇 <polygon> , 在看原始碼的時候比較可以清楚分辨是 <polygon> 的多邊形還是 <polyline> 的線; 此外 <polygon> 比 <polyline>少一個字母, 也不用在 points 最後指定回第一點,多少可以節省一點檔案大小吧!

其他像是 <rect> <circle> <ellipse> 的元素則可以畫出矩形、圓形、橢圓形, 目前我還沒用到,規則不難,搜尋一下教學網頁就可找到,在這就不多寫了。

突然看到也有 fill-opacity="0.1" stroke-opacity="0.9" 的屬性,大概就是設定顏色的不透明度吧,不指定的話應該就是 1 。

另外如果兩個元素的圖形有重疊,那麼原始碼寫在後面的元素會壓在上面, 上面的圖形有設透明的話就可以看到被壓在下面的圖形了。

4. 文字 <text>

<text> 元素不難, 跟上面不太一樣的地方是要顯示的文字要寫在 <text> 和 </text> 之間, 詳細可參考 教學一 教學二

<text x="200" y="100" fill="red" font-family="Verdana" font-size="73">Hello, I am Doofenshmirtz</text>

其中 x, y 代表位置座標,以 text-anchor 來決定文字哪裡對齊指定座標, 有 start, middle, end 的選擇,分別為文字的左下角、中間下面和右下角, 不指定的話預設是 start 。

然後 fill 、 font-family 和 font-size 代表顏色、字型和大小, 其中字型也可以輸入中文的"標楷體"或"微軟正黑體"之類的。

此外 stroke 和 stroke-width 也可以使用,如此一來文字會有外框,滿有趣的。

5. 複製與變換 <defs><g id= >、<use>、transform

如果同樣的元素需要大量使用, <use> 就很方便, 可以複製前面提到的其他元素來重複使用,算是 svg 語法中最好用的元素之一吧, 就好像杜芬舒斯發明的 複製終結者 複製八終結者 一樣方便。

首先,在 <defs></defs> 之間用 <g id="..."></g> 來定義想複製的東西,每組 <g> 都取一個不同的 id ,像這樣:

<defs>
    <g id="s1">
        <rect x="50" y="50" width="50" height="50" />
        <circle cx="50" cy="50" r="50" />
    </g>
    <g id="s2">
        <rect x="60" y="60" width="60" height="60" />
        <circle cx="60" cy="60" r="60" />
    </g>
</defs>

然後要用的時候,像這樣:

<use xlink:href="#s1" x="50" y="50" />
<use xlink:href="#s2" x="200" y="50" transform="translate(100 50) rotate(-35 27 6)" />

就可以將 id 為 s1 的那組東西複製到原本定義的位置平移 x="50" y="50" 的地方,多寫幾個 <use> 就可以多複製幾次到指定的位置。

此外可以加入 transform 進行變換, translate 平移 x, y 座標和 rotate 順時鐘旋轉一個角度以 x, y 座標為中心, 要複雜一點也可以寫成 matrix 或其他方式。

另外也可以在 <use> 裡加入 stroke 那些屬性, 測試結果是原本定義的元素如果已經設定那個屬性則不會受影響,否則就會套用 <use> 裡設定的屬性。

其實在設定 <g> 的時候也可以加入 stroke 那些屬性, <g> 裡面的元素如果已經設定那個屬性則不會受影響,否則就會套用 <use> 裡設定的屬性。 (先看 元素本身 -> g -> use) <g>的好處是可以將元素集合起來統一設定屬性。

然後如果沒加 <defs> 原本定義的東西就會在原地而不會消失, 有設 <g id= > 的話一樣可以用 <use> 複製 (其實只要元素有設定 id 都可以用 <use> 複製)。 此外 <defs> 也可以定義其他東西,以後再研究囉。

transform 的屬性似乎也可以加在其他元素裡直接進行轉換。

後記

最後這些看似複雜,其實只要了解 svg 裡的每個標籤和屬性可以做些什麼, 發揮創意隨意嘗試各種組合,觀察產生的結果,就可以拼湊出有趣的東西。

雖然不像一般寫程式要用到 if, for 之類的邏輯, 思考如何善用 svg 語法拼湊出想要的效果有時也很有挑戰性, 甚至還可以藉由寫程式來產生 svg 呢! 就算覺得透過寫原始碼來畫圖太困難或是不夠直覺,善用市面上很多好用的軟體如 Inkscape ,就可以從圖形介面創作或是修改 svg 圖形。


其他參考資料及教學文件:
http://www.w3.org/TR/SVG/expanded-toc.html
https://developer.mozilla.org/en-US/docs/Web/SVG/Element
http://www.w3schools.com/svg/

No comments :

Post a Comment