這一篇是講 SVG 的座標系統,在這以前若是你對 SVG 的基礎知識還不是很瞭解,能夠先點這裏學習 深刻理解 SVG 系列(一) —— SVG 基礎。html
和不少計算機繪圖所使用的座標系統同樣,SVG 也使用了網格座標系統。這種座標系有以下幾個特色:segmentfault
X 軸
的正方向向右
,從 0,0 點開始向右, x 逐漸增大。Y 軸
的正方向向下
,從 0,0 點開始向下, y 逐漸增大。<svg width="100" height="100" style="outline: 2px solid red"> <rect x="0" y="0" width="50" height="50" fill='green'/> </svg>
以 0,0 爲起始點,畫一個 100 * 100 的矩形
上面咱們提到了畫布和視窗分別對應兩個座標系,一個視窗座標系,一個用戶座標系。這兩個座標系都具備咱們上面提到的網格座標系的幾個特色。svg
這兩個座標系一開始是徹底重合的,它們的原點和座標都是徹底一致的,也就是說初始用戶座標系的原點就位於視窗的左上角,也是 X 軸正向向右,Y 軸正向向下。學習
雖然一開始它們是兩個徹底同樣的座標系,但既然是兩個座標系,就意味着它們能夠是不同的。你能夠經過 viewBox 去改變這種默認對齊的方式,接下來的內容會講到。spa
以前的章節中,咱們全部的 SVG 內容看起來都像是基於視圖座標系來繪製的,由於初始視窗座標系和初始用戶座標系徹底相同,但在這一節中,咱們會經過 viewBox 來聲明本身的用戶座標系。3d
viewBox 是用來把 SVG 內容繪製到畫布上的座標系。它的字面意思是視圖盒子,只有出如今這個盒子區域裏面的 SVG 內容才能被看到,你能夠理解爲 SVG 圖形真正的可見區域。code
viewBox = <min-x> <min-y> <width> <height>
viewBox 接收四個參數值,分別是 min-x
,min-y
,width
,height
。htm
min-x
和 min-y
決定了 viewBox 的左上角,width
和 height
決定了 viewBox 的寬和高。注意 width 或 height 若是設置成 0
,會禁止元素的渲染。blog
<svg width="100" height="100" viewBox="0 0 50 50"> <!-- SVG content --> </svg>
設置 viewBox="0 0 50 50"
以後會發生什麼?ci
經過改變 min-x 和 min-y 的值能夠將 viewBox 聲明的區域進行平移。
以座標點 0,0 爲圓心,半徑爲 50px 畫一個圓,咱們只能看到圓的 1/4,如圖一:
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
圖一
經過設置 viewBox="-50 -50 100 100"
,咱們能夠看到一整個圓。以下圖:
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
圖二
經過 viewBox 的 min-x
和 min-y
兩個參數,咱們將 viewBox 聲明的區域分別向左和上進行了平移,這時咱們以 0,0 爲圓心,半徑爲 50 畫圓,正好可以將整個圓顯示到 viwBox 聲明的區域中,而後再將這個座標系映射到 100px * 100px 的視窗中,就大功告成了。
經過改變 width 和 height 的值能夠縮放 viewBox 聲明的區域。
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
當 viewBox 的寬高小於視窗的寬高時,至關於放大。
<svg width=100 height=100 viewBox="0 0 50 50" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
當 viewBox 的寬高大於視窗的寬高時,至關於縮小。
<svg width=100 height=100 viewBox="0 0 200 200" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
由於多設備適配的需求,不少時候咱們指望 SVG 圖形可以在不一樣的屏幕上放大或縮小,可是咱們又不但願每次都去修改 <svg>
的 width
和 height
,這時百分比就很是有用了。
若是給視窗設置 width: 100%
和 height: 100%
,那麼視窗的寬高就由它父元素的寬高決定,咱們能夠經過調整其父元素的寬高來放大和縮小 SVG 視窗,而不用修改 <svg>
的 width 和 height。僅僅是這樣還不夠,咱們還須要經過 viewBox 來將 SVG 圖形放大到整個視窗區域。
<div style="width:100px; height:100px;"> // 你能夠試着經過修改 div 的寬高來改變 SVG 圖形的大小 <svg width="100%" height="100%" style="outline: 2px solid red" viewBox="0 0 100 100"> <rect x="0" y="0" width="100" height="100" fill="green"/> </svg> </div>
利用 viewBox 實現上半圓
<svg width=100 height=100 viewBox="-50 -100 100 100" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
在紙上畫出 viewBox 聲明的區域,以下圖:
橙色區域爲 viewBox 聲明的區域,從粉色的區域移動到橙色區域能夠得出 viewBox 的 min-x = -50 min-y = -100,在這個區域只有上半圓可見,所以咱們最後看到的也就只是這個上半圓。
請參考第一題,在紙上畫出下面 SVG 的座標系,在座標系上畫出每一個元素,以及 viewBox 的區域。
<svg width=100 height=100 viewBox="0 -50 100 100" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
preserveAspectRatio 屬性用來強制統一縮放比,以保持圖形的寬高比。
若是 viewBox 的寬高比和 SVG 視窗的寬高比不一樣,那麼在拉伸 viewBox 來適應視窗的時候,就可能致使 SVG 圖形發生扭曲。這個時候 preserveAspectRatio 就派上用場了。
preserveAspectRatio = <align> <meetOrSlice>?
align
表示 viewBox 如何與 viewport 對齊。meetOrSlice
是可選的,表示如何保持寬高比。align
align 的值有不少,爲了方便理解,咱們先把它最基本的值拆分出來,以下:
值 | 含義 |
---|---|
none | 經過拉伸 viewBox 來適應整個視窗,無論寬高比 |
xMin | viewBox 和 viewport 左邊緣對齊 |
xMid | viewBox 和 viewport x 軸中心對齊 |
xMax | viewBox 和 viewport 右邊緣對齊 |
YMin | viewBox 和 viewport 上邊緣對齊 |
YMid | viewBox 和 viewport y 軸中心對齊 |
YMax | viewBox 和 viewport 下邊緣對齊 |
而後再自由組合 x,y 就能能夠了,好比:
xMinYMin => 左-上對齊 xMidYmid => 中-中對齊
meetOrSlice
值 | 含義 |
---|---|
meet | 保持寬高比縮放 viewBox 以適應 viewport,相似於 background-size: contain |
slice | 保持寬高比同時比例小的方向放大填滿 viewport,相似於 background-size: cover |
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
在上面的例子中,咱們並無設置 preserveAspectRatio ,可是根據咱們以前講過的知識,不難發如今 <svg>
上做用着一個隱形的 preserveAspectRatio="xMidYMid meet"
。
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red" preserveAspectRatio="xMidYMid meet"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
那麼 preserveAspectRatio="xMidYMid meet"
是如何做用在 SVG 上的呢?請看下面的圖:
上圖中 viewport 寬 200 高 100,viewBox 寬 100 高 100, x 橫軸比例是 2, y 縱軸比例是 1。xMidYMid
讓 viewBox 和 viewPort 的中心對齊,和 viewport y 軸上邊緣對齊。meet
的做用是讓 viewBox 保持寬高比的同時,徹底在 viewport 中顯示。
由於這裏最小的縱向比例是 1 ,因此 viewBox 沒有任何的縮放。
爲了更好的去感覺縮放,咱們將 viewBox 的寬度從 100 調整到 300,其它保持不變。
<svg width="200" height="100" viewBox="0 0 300 100" style="outline: 2px solid red" preserveAspectRatio="xMinYMin meet"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
這時 viewBox 的寬度超過 viewport 的寬度了(如圖一),因此 viewBox 就會縮小以適應 viewport,由於 meet 會讓 viewBox 保持比例來進行縮放,因此你能夠想象成按住viewBox 的右下角,縮小 viewBox 至 viewport 的大小 (如圖二)。
說完了 meet
下面咱們再來講說 slice, slice 雖然會保持寬高比進行縮放,可是會在比例小的方向放大填滿 viewport。好比設置 viewBox 寬 100 高 100,viewport 寬 200 高 100,在 viewport 的 x 軸方向還有空間,因此會將 viewBox 在橫軸上進行放大,結果就是咱們的好好的正方形被拉成了矩形。
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red" preserveAspectRatio="xMidYMid slice"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
在學習 SVG 的過程當中,動手畫圖真的很是的重要。這也是爲何我一直嘗試圖解 SVG,在以前的練習中也要求你們去畫圖的緣由。畫圖可以幫助你去理解 SVG 的座標系,理解每個元素或者每個屬性在座標系中是怎樣體現出來的。因此但願你們在學習 SVG 的過程當中,多去動手畫圖,最後達到可以「裸寫」 SVG 的境界!