- SVG入門
- SVG 元素
- 簡單的形狀
- rect
- circle
- ellipse
- line
- text
- path
- SVG 樣式
- 分層和繪圖順序
- 透明度
SVG入門
當我們用SVG生成和操作一些炫酷的效果時,D3是最佳選擇。使用div和其他原生HTML元素繪圖也是可以的,但是太笨重,而且會受到不同瀏覽器的限制,傳達出的視覺效果會有不一致的影響。使用SVG更可靠,視覺上更一致,最重要的就是方便,快捷。
像Illustrator這樣的矢量繪圖軟件可用于生成SVG文件,但我們更需要學習如何使用代碼生成它們。
SVG 元素
可縮放矢量圖形是基于文本的圖像格式。每一個SVG圖像都是使用類似HTML的標識代碼定義生成的。SVG代碼可以直接包含在任何HTML文檔中。除了IE 8及更早的版本外,其他每一個Web瀏覽器都支持SVG。
SVG是基于XML的,因此你會注意到沒有結束標記的元素必須是自動關閉的,例如:
<element></element> <!-- 結束標記 -->
<element/> <!-- 自動關閉標記 -->
在繪制任何SVG圖像之前,必須創建一個SVG元素。將SVG元素視為渲染視覺效果的畫布。其實這方面,SVG在概念上有點類似于HTML中的canvas元素。SVG是可以指定寬度和高度的,如果不指定那么SVG將在其封閉元素中占用盡可能多的空間大小。
下面是一個指定空間大小的SVG:
<svg width="500" height="50">
</svg>
如果你將這段代碼放在你的HTML中,會形成一塊空白區域,此時你可以鼠標右鍵選擇空白區域,選擇檢查
,將會發現:
會看一個SVG元素,它占用了500個水平像素和50個垂直像素。但是看起來不像,下面解釋。
瀏覽器將像素視為默認度量單位。我們指定的尺寸是500和50,而不是500px和50px。我們可以明確指定px,或者是任意數量的其他被支持的單位,比如:em,pt,in,cm,mm。
簡單的形狀
SVG標記之間包含很多可視化的元素,包括rect,circle,ellipse,line,text和path。
如果你比較熟悉計算機圖形編程,那么你一定知道通常基于像素的坐標系統,其中(0,0)是我們桌面的最左上角。在(x,y)中,x表示x軸,y代表y軸,此時增加x值向右移動,而增加y值向下移動。
圖像代碼如下:
<svg width="505" height="65"><line x1="5" y1="5" x2="5" y2="50" stroke="gray" stroke-width="1"></line><line x1="5" y1="50" x2="0" y2="45" stroke="gray" stroke-width="1"></line><line x1="5" y1="50" x2="10" y2="45" stroke="gray" stroke-width="1"></line><line x1="5" y1="5" x2="500" y2="5" stroke="gray" stroke-width="1"></line><line x1="500" y1="5" x2="495" y2="0" stroke="gray" stroke-width="1"></line><line x1="500" y1="5" x2="495" y2="10" stroke="gray" stroke-width="1"></line><circle cx="5" cy="5" r="3" fill="#008"></circle><text x="10" y="20">0,0</text><circle cx="105" cy="25" r="3" fill="#008"></circle><text x="110" y="40">100,20</text><circle cx="205" cy="45" r="3" fill="#008"></circle><text x="210" y="60">200,40</text>
</svg>
rect
使用rect繪制一個矩形。使用x和y指定左上角的坐標,使用寬度和高度指定尺寸。這個矩形填滿了SVG整個空間:
<svg width="500" height="50"><rect x="0" y="0" width="500" height="50"/>
</svg>
效果:
circle
circle標簽可以畫一個圓圈。使用cx和cy指定中心的坐標,使用r指定半徑。這個圓圈位于我們500個像素寬的SVG中間,因為它的cx(center x)值為250。
<svg width="500" height="50"><circle cx="250" cy="25" r="25"/>
</svg>
效果:
ellipse
ellipse和circle是類似的,但是每個軸需要單獨的半徑值,由rx和ry指定。
<svg width="500" height="50"><ellipse cx="250" cy="25" rx="100" ry="25"/>
</svg>
效果:
line
line是畫一條直線。使用x1和y1指定線一端的坐標,使用x2和y2指定另一端的坐標。必須為要顯示的線指定畫筆顏色。
<svg width="500" height="50"><line x1="0" y1="0" x2="500" y2="50" stroke="black"/>
</svg>
效果:
text
text用來渲染文字的。使用x指定左邊緣的位置,使用y指定類型基線的垂直位置。
<svg width="500" height="50"><text x="250" y="25">Easy-peasy</text>
</svg>
效果:
如果沒有有意指定text的字體樣式,那么text將繼承其父元素的CSS指定字體樣式(稍后詳細介紹樣式文本)。上面的文字樣式,我們可以自定義設置,如下:
<svg width="500" height="50"><text x="250" y="25" font-family="sans-serif"font-size="25" fill="gray">Easy-peasy</text>
</svg>
效果:
另外注意,當任何可視化元素在SVG的邊緣上運行時,它將被剪裁。使用文字時要小心,否則會出現y操作設置無效,當我們將基線y設置為50時,可以看到這種情況發生,與SVG的高度相同。
<svg width="500" height="50"><text x="250" y="50" font-family="sans-serif"font-size="25" fill="gray">Easy-peasy</text>
</svg>
效果:
path
path用于繪制比上面的形狀更復雜的東西(如地圖的國家輪廓),這個后續我們再做介紹,現在暫時使用一些簡單的形狀入門。
SVG 樣式
SVG的默認樣式是黑色填充,沒有畫筆。如果需要其他任何內容,則必須將樣式應用于元素。
常見的SVG屬性是:
- fill - 填充的顏色。與CSS一樣,顏色可以指定為
- named colors - orange
- hex values - #3388aa or #38a
- RGB values - rgb(10, 150, 20)
- RGB width alpha transparency - rgba(10, 150, 20, 0.5)
- stroke - Stroke屬性定義一條線,文本或元素輪廓顏色
- stroke-width - 定義了一條線,文本或元素輪廓厚度
- opacity - 透明度,一個在0.0-1.0之間的數值
使用text,您還可以使用這些屬性,就像在CSS中一樣:
- font-family
- font-size
其實SVG的樣式可以使用CSS樣式規則。
以下是一些直接應用于圓形的樣式屬性作為屬性:
<svg width="500" height="50"><circle cx="25" cy="25" r="22"fill="yellow" stroke="orange" stroke-width="5"/>
</svg>
效果:
或者,我們可以去除樣式屬性,為圓圈分配一個class(就像它是一個普通的HTML元素)
<svg width="500" height="50"><circle cx="25" cy="25" r="22" class="pumpkin"/>
</svg>
然后將fill,stroke和stroke-width規則放入以新類為目標的CSS樣式中:
.pumpkin {fill: yellow;stroke: orange;stroke-width: 5;}
CSS方法有一些明顯的好處:
- 可以同時對多個元素進行樣式設定,比如:
<svg width="500" height="50"><circle cx="25" cy="25" r="22" class="pumpkin"/><circle cx="80" cy="25" r="20" class="pumpkin"/>
</svg>.pumpkin {fill: yellow;stroke: orange;stroke-width: 5;}
- CSS代碼更方便閱讀(相比內聯屬性)
- CSS代碼可能更易于維護,并且可以更快的實現設計更改要求
但是,使用CSS代碼定義SVG的樣式可能會讓一些人感到不安。畢竟,fill,stroke和stroke-width不是CSS屬性。(與之CSS等價物是背景顏色和邊框)。
分層和繪圖順序
Layering and Drawing Order(分層和繪圖順序)。
在SVG中沒有層,也沒有真正的深度概念,就好比z-index。SVG不支持CSS的z-index屬性,因此形狀只能排列在二維x,y平面內。
然而,如果我們繪制多個形狀,它們會發生重疊,如下:
<svg width="500" height="50"><rect x="0" y="0" width="30" height="30" fill="purple"/><rect x="20" y="5" width="30" height="30" fill="blue"/><rect x="40" y="10" width="30" height="30" fill="green"/><rect x="60" y="15" width="30" height="30" fill="yellow"/><rect x="80" y="20" width="30" height="30" fill="red"/>
</svg>
效果:
元素編碼的順序決定了對應元素的深度順序。紫色方塊第一個出現,因此第一個被渲染,然后藍色方塊呈現在紫色方塊的頂部,接下來就是綠色方塊,依此類推。
當有一些不應該被其他元素遮擋的視覺元素時,繪制順序就變得很重要。例如,在一個散點圖上顯示軸或值標簽,軸和標簽應該是最后渲染,所以它們出現在任何其他元素的上層。
透明度
Transparency(透明度)
當可視化中的元素重疊但是又必須保持可見,這時可以使用透明度;或者希望突出顯示其他元素和不強調某些元素時,透明度就非常有用。
有兩種方法可以應用透明度:
- 使用帶有alpha的RGB顏色
- 設置不透明度值。
可以在任何一個設定顏色的元素中使用rgba(),例如填充或者描邊。對于紅色,綠色和藍色,rgba() 需要0到255之間的三個值,以及介于0.0到1.0之間的alpha(透明度)值。
例如:
<svg width="500" height="50"><circle cx="25" cy="25" r="20" fill="rgba(128, 0, 128, 1.0)"/><circle cx="50" cy="25" r="20" fill="rgba(0, 0, 255, 0.75)"/><circle cx="75" cy="25" r="20" fill="rgba(0, 255, 0, 0.5)"/><circle cx="100" cy="25" r="20" fill="rgba(255, 255, 0, 0.25)"/><circle cx="125" cy="25" r="20" fill="rgba(255, 0, 0, 0.1)"/>
</svg>
效果:
使用rgba() 時,透明度將獨立應用于填充和描邊顏色。以下圓圈填充的是75%不透明,而它們的筆畫只有25%不透明:
<svg width="500" height="50"><circle cx="25" cy="25" r="20"fill="rgba(128, 0, 128, 0.75)" stroke="rgba(0, 255, 0, 0.25)" stroke-width="10"/><circle cx="75" cy="25" r="20"fill="rgba(0, 255, 0, 0.75)"stroke="rgba(0, 0, 255, 0.25)" stroke-width="10"/><circle cx="125" cy="25" r="20"fill="rgba(255, 255, 0, 0.75)"stroke="rgba(255, 0, 0, 0.25)" stroke-width="10"/>
</svg>
效果:
將透明度應用于整個元素,請設置不透明度屬性。這是一些完全不透明的圓圈。
效果:
下面是不同透明度的圓圈:
<svg width="500" height="50"><circle cx="25" cy="25" r="20" fill="purple" stroke="green" stroke-width="10"opacity="0.9"/><circle cx="65" cy="25" r="20" fill="green"stroke="blue" stroke-width="10"opacity="0.5"/><circle cx="105" cy="25" r="20" fill="yellow"stroke="red" stroke-width="10"opacity="0.1"/>
</svg>
效果圖: