閱讀目錄
一:理解viewport
該屬性表示的是SVG可見區域的大小。或者也可以叫畫布的大小。就好比我們的電腦螢幕,我們只能看到我們電腦螢幕的可視區裡面的內容,但是看不到電腦螢幕之外的內容。比如如下程式碼:
<svg width="200" height="200" style="border: 1px solid red"></svg>
如上程式碼,我們定義了一個svg的畫布,寬度為200px,高度為200px,邊框的顏色為紅色,1畫素,實線。因此該程式碼的顯示效果在頁面上顯示如下:
如上程式碼,我們設定了svg的畫布大小為200px*200px, 如果沒有帶單位的話,該單位預設是 px(畫素)。當然也有其他單位:比如:
em: 相對於父元素的字型大小。
ex: 相對於小寫字母的 'x' 的高度(不常用)
px: 畫素(在支援css2的圖形系統中,每英寸為96畫素)。
pt: 點(1/72英寸)
pc: 12點(1/6英寸)。
cm: 釐米
mm: 毫米
in: 英寸
當然我們還可以指定svg元素的width和height為百分比,當我們的svg元素巢狀在一個div裡面去的話,那麼它的百分比是相對於外層的div元素的寬度和高度進行計算的。當然如果我們的svg元素為根元素的話,那麼它的百分比是相對於視窗的尺寸來計算的。比如如下程式碼:
<div style="width:400px;height:400px; border: 1px solid red; "> <svg width="20%" height="20%" style="border: 1px solid red;"></svg> </div>
效果如下所示:
如上圖我們可以看到,我們的svg的寬度和高度為82px; 因為div元素的寬度和高度為400px; 20%的話,20% * 400 = 80px; 再加上2px的邊框,因此一共82px。
如果我們沒有給svg設定寬度和高度的話,它預設的寬度為300px,高度為150px; 如下程式碼:
<div style="width:400px;height:400px; border: 1px solid red; "> <svg style="border: 1px solid red;"></svg> </div>
執行的效果如下所示:
理解預設使用者座標
在svg中有一個預設的座標系統,其中 水平座標(x座標)向右遞增的,垂直座標(y座標)是向下遞增的。原點座標是(0, 0). 該座標系統類似於我們數學幾何中的座標。
比如我們現在建立一個200px寬,200px高的視口,然後我們在裡面繪製一個矩形,該矩形左上角在座標(10, 10)的位置,該矩形的寬度為50px, 高度為 50px,基本程式碼如下:
<svg style="border: 1px solid red;" width="200" height="200"> <rect x="10" y="10" width="50" height="50" style="stroke: black; fill:none;"></rect> </svg> <div style="width:100px;height:100px;margin-left:10px;background: red;"></div>
執行效果如下:
如上可以看到,我們在svg上繪製了一個小矩形,矩形的寬度為50px,高度也是為50px,然後該矩形的左上角在座標(10, 10)的位置,因此該座標點離右邊(x座標向右是遞增的)和下邊(y座標向下是遞增的)偏移10px;然後繪製了一個寬度為50px,和高度為50px的小矩形。我們也可以看到我們下面還有一個div元素,設定了 margin-left: 10px; 其實在我們的矩形內部設定了偏移10px,和我們的margin-left 是一個意思的。
二:理解viewBox
viewBox="x, y, w, h"; 該屬性的含義是可視區盒子,即畫布的可視區。
viewport 和 viewBox 分別有自己的座標系,預設情況下,該兩個座標系是重合的,即轉換關係是 1:1。
x: 指左上角的座標,y: 左上角的縱座標,w: 指寬度,h: 指高度
1. 畫布(viewport)、可視區(viewBox) 的寬度的高度相等情況
比如如下程式碼:
<div style="width:100%;display:inline-block;"> <svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,400,200"> <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> </div>
如上程式碼,svg的畫布大小,寬度為400px,高度為200px,然後使用viewBox屬性定義畫布的可視區的大小寬度也是400px,高度也是200px, 因此該兩個座標系是重合的,因此我們使用 rect 來建立矩形的話,定義寬度和高度分別為100px,x軸和y軸的偏移位置為10px; 效果如下所示:
2. 畫布不變,可視區的寬度減小的情況
比如如下程式碼,可視區的寬度減少100px, 如下程式碼所示:
<div style="width:100%;display:inline-block;"> <svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200"> <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> </div> <div style="border: 1px solid red;width:300px;height:200px; margin-left: 60px;"></div>
執行結果如下所示:
如上程式碼,畫布大小的寬度是400px,可視區的寬度變成300px; 因此為了使他們的中心點能重合的話,因此需要向右移動的距離 = 400 - 300 / 2 = 50px; 由於 rect 中的x偏移了10px,因此加起來就是偏移了60px了,可以把下面的div作為參照物即可看到。
如下示意圖所示解釋
下面我們繼續把可視區的寬度改為200px; 如下程式碼:
<div style="width:100%;display:inline-block;"> <svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,200,200"> <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> </div> <div style="border: 1px solid red;width:200px;height:200px; margin-left: 110px;"></div>
然後我們執行結果如下所示:
可以看到,矩形需要偏移的距離 = 400-200/2 + 10 = 110px; 從下面的div中的margin-left 我們可以看到 偏移110px的時候,才能使 畫布(viewport)和可視區(viewBox)的中心點能夠重合。我們可以繼續看如下示意圖所示:
3. 畫布不變,可視區的高度減小的情況
如下程式碼:
<svg style="float:left;border: 1px solid red;" width="200" height="200" viewBox="0,0,200,100"> <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="float:left; margin-left: 20px; border: 1px solid red;width:200px;height:100px;margin-top:60px"></div>
執行結果如下所示:
如上可以看到,矩形向下偏移的距離 = 200 - 100 / 2 + 10 = 60px; 因此我們可以看到我們的下面的div元素 margin-top:60px; 就可以對齊了。
4. 可視區不變,畫布寬度變小
如果可視區不變的話,畫布寬度減少的話,那麼矩形也要等比例縮小,比如如下程式碼:
<svg style="float:left;border: 1px solid red;" width="100" height="200" viewBox="0,0,200,200"> <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="float:left; margin-left: 20px; border: 1px solid red;width:100px;height:200px;margin-top:50px"></div>
執行結果如下所示:
如上可以看到,矩形本來大小是 100px*100px,現在畫布的寬度改成100px了,那麼矩形也變成原來的一半了,至於向下移動距離的計算 = 200 - 100 / 2 = 50px;
5. 可視區不變,畫布的高度變小
可視區不變,畫布高度變小的話,那麼矩形也要等比例縮放;如下程式碼所示:
<div style="width:100%;display:inline-block;"> <svg style="float:left;border: 1px solid red;" width="200" height="80" viewBox="0,0,200,200"> <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> </div> <div style="margin-top:10px;border: 1px solid red;width:200px;height:80px;margin-left:60px"></div>
如上程式碼;可視區的高度是畫布的 200/80 = 2.5倍, 因此矩形高度也變成原來的2.5倍分之1. 因此計算公司如下:
200 100
-—— = ---- = 40px
80 x
因此矩形的寬度和高度等比例縮放到 40px; 偏移的距離計算方式 = 200 - 80 / 2 = 60px; 因此向右偏移 60px 即可。
如下所示:
也就是說,如果畫布的高度變小的話,那麼偏移是向右的,如果畫布的寬度變小,那麼偏移是向下的。
6. 可視區寬度和高度大於畫布的寬度和高度
如下程式碼:
<svg style="float:left;border: 1px solid red;" width="45" height="135" viewBox="0,0,200,200"> <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="float:left;margin-left:20px;border: 1px solid red;width:45px;height:135px;margin-top:46px"></div>
執行結果如下所示:
如果可視區寬度和高度大於畫布的寬度和高度的話,那麼 矩形的寬度和高度的計算方式以 寬度和高度最小的那個來等比例計算,什麼意思呢?我們如上的畫布的寬度是45px,高度是135px,那麼寬度小於高度,因此需要按照45px來計算,因此計算方式 =
200 100
--- = ----
45 x
最後 x = 22.5px 了,由於畫布的寬度小於高度,因此需要向下偏移,那麼偏移的距離計算方式 = 135 - 45 / 2 = 45px; 因此向下偏移45px即可,至於上面的div元素 margin-top 為46px,那是因為帶了一畫素邊框。
為了驗證這個邏輯,我們可以讓畫布的寬度大於高度,如下程式碼所示:
<svg style="border: 1px solid red;" width="145" height="43" viewBox="0,0,200,200"> <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="border: 1px solid red;width:145px;height:43px;margin-top:10px; margin-left: 52px;"></div>
執行效果如下所示:
矩形的大小計算方式 =
200 100
--- = ---- = 21.5px
43 x
也就是說 畫布的寬度和高度,那個小就根據那個來縮放比例,現在是高度為 43 x, 43px 小於 寬度 145px, 因此 按照高度 43px 來計算,因此最後我們的矩形的等比例縮放的大小為 21.5px; 那麼向右偏移的距離 = 145 - 43 / 2 = 51px 了,同理我們上面的div參考元素 margin-left: 52px, 那是因為邊框有1px;
但是如果如下程式碼:
<svg style="border: 1px solid red;" width="145" height="43" viewBox="0,0,200,80"> <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="border: 1px solid red;width:145px;height:43px;margin-top:10px; margin-left: 19px;"></div>
執行效果如下了:
矩形的計算方式 =
43 x
--- = ---- = 53.75px
80 100
然後偏移的距離 = 80 - 43 / 2 = 37 / 2 = 19px 左右。
三:理解 preserveAspectRatio
該屬性的作用是:它允許我們指定被縮放的影象相對視口的對齊方式。基本的使用方法如下所示:
preserveAspectRatio = "alignment [meet | slice]"
其中 alignment 指定軸和位置,預設值為 preserveAspectRatio = "xMidYMid meet";
preserveAspectRatio 該屬性是應用在SVG上,且和viewBox屬性配合一起使用的。viewBox屬性值可以指明是否可以等比例縮放(寬高比相同的情況下),以擴充套件到viewport指定的大小區域中。
該物件第一個引數有如下9個不同的值,分別為如下:
xMinYMin,
xMinYMid,
xMinYMax,
xMidYMin,
xMidYMid,
xMidYMax,
xMaxYMin,
xMaxYMid,
xMaxYMax
如上 x 和 y 表示對齊的軸線,x 表示水平方向物件(往右邊是正數),y表示縱向物件(往下是正數)。min, mid, max 表示對齊的方式。min 是往座標小的方向對齊,mid是居中對齊,max是往座標大的方向對齊。
第二個引數有3個值可選,分別為:meet 和 slice 和 none。
meet 的含義是:viewBox保持等比例縮放,整個viewBox在viewport中都是可見的。在滿足2個約束的條件基礎上,儘可能的放大viewBox,當viewport的寬高比和viewBox的寬高比不匹配的時候,那麼取寬高比中較小的那個。
slice 的含義是:修剪viewBox保持等比例縮放,整個viewport區域會被viewBox覆蓋。在滿足2個約束的條件基礎之上,儘可能的縮小viewBox,當viewport的寬高比和viewBox的寬高比不匹配時,取寬高縮放比中比較大的那個。
none 的含義是:不強制等比例縮放,儘量以viewBox和viewport以實際的寬高比來縮放圖形,儘量把寬度和高度擴充套件到這個viewport上。最後的結果就會使影象變模糊。
我們分別來看下demo:
1. preserveAspectRatio="xMinYMin meet"情況下
強制縮放比例,xMin:viewBox的x軸和viewport的x軸最左邊對齊,YMin:viewBox的y軸和viewport的y軸最左邊對齊。
如下程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMin meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行效果如下:
如上我們看到,當我們設定 xMinYMin 的時候,意味著 x座標和y軸座標在原點上(0, 0)。
2. preserveAspectRatio="xMinYMid meet"情況下
強制縮放比例,xMin:viewBox的x軸和viewport的x軸最左邊對齊,YMid:viewBox的y軸和viewport的y軸中點對齊。
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMid meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行效果如下:
示意圖如下:
注意: 如上 xMinYMid 和 yMidXMin 效果是不一樣的,最前面的優先順序最大,所以它會先以上面的 xMin最左端對齊。
3. preserveAspectRatio="xMinYMax meet"情況下
強制縮放比例,xMin:viewBox的x軸和viewport的x軸最左邊對齊,YMax:viewBox的y軸和viewport的y軸最下邊對齊
如下程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMax meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行效果如下圖所示:
示意圖如下所示:
4. preserveAspectRatio="xMidYMin meet"情況下
強制縮放比例,xMid:viewBox的x軸的中心和viewport的x軸中心對齊,yMin: viewBox的Y軸最上方和viewport的y軸最上方對齊。
如下程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMidYMin meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行效果如下圖所示:
示意圖如下所示:
5. preserveAspectRatio="xMidYMid meet"
強制等比例縮放,xMid:viewBox的x軸中點和viewport的x軸中點對齊,YMid: viewBox的y軸中點 和 viewport的y軸中點對齊。
如下程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMidYMid meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行結果如下所示:
如上程式碼,畫布大小的寬度是400px,可視區的寬度變成300px; 因此為了使他們的中心點能重合的話,因此需要向右移動的距離 = 400 - 300 / 2 = 50px; 由於 rect 中的x偏移了10px,因此加起來就是偏移了60px了,可以把下面的div作為參照物即可看到。
如下示意圖所示解釋
如上程式碼是我們之前分析的程式碼,因為畫布是400px,我們的可視區viewBox的寬度變成300px,但是我們的 preserveAspectRatio 的預設屬性值為:"xMidYMid meet"; 也就是說 x 軸方向是居中的,y軸方向是居中的,因此他們的中心點是相同的。
6. preserveAspectRatio="xMidYMax meet"
強制等比例縮放,xMid:viewBox的x軸中點和viewport的x軸中點對齊,YMax: viewBox的y軸最下方和 viewport的y軸最下方對齊。
程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMidYMax meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
效果如下:
如下示意圖所示解釋
7. preserveAspectRatio="xMaxYMin meet"
強制等比例縮放,xMax:viewBox的x軸和viewport的x軸最右邊對齊,YMax: viewBox的y軸和 viewport的y軸最上方對齊。
程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMaxYMin meet" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg> <div style="width:100%;display: inline-block;"> <div style="margin-left:110px;border: 1px solid red;width:300px;height:200px;"></div> </div>
效果如下:
如下示意圖所示解釋
如上程式碼;xMax是指 viewBox的x軸和viewport的x軸最右邊對齊,且 YMax: viewBox的y軸和 viewport的y軸最上方對齊。因此如上示意圖,如上面使用了div元素來做參考,margin-left:110px; 因為 畫布的大小是400px,我們的viewBox 是300px; 且rect元素向右移動了10px; 因此一共就是110px了。
8. preserveAspectRatio="xMaxYMid meet"
強制等比例縮放,xMax:viewBox的x軸和viewport的x軸最右邊對齊,YMax: viewBox的y軸和 viewport的y軸中心對齊。
效果和上面第七點是一樣的。這裡就不多解釋了。
9. preserveAspectRatio="xMaxYMax meet"
強制等比例縮放,xMax:viewBox的x軸和viewport的x軸最右邊對齊,YMax: viewBox的y軸和 viewport的y軸最下邊對齊。
效果和上面第七點是一樣的。這裡就不多解釋了。
10. preserveAspectRatio="xMinYmin slice"
slice 的含義是:修剪viewBox保持等比例縮放,整個viewport區域會被viewBox覆蓋。在滿足2個約束的條件基礎之上,儘可能的縮小viewBox,當viewport的寬高比和viewBox的寬高比不匹配時,取寬高縮放比中比較大的那個。
程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMin slice" > <rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
效果如下:
如上我們可以看到我們的矩形的寬度和高度變為 133.33px * 133.33px了,為什麼呢?那是因為我們的viewport的寬度是400px,我們的viewBox是300px; 因此 400/300 = 1.33, 因此rect的寬度和高度的大小都需要在原來的寬度和高度都乘以1.33來鋪滿我們的viewport(畫布)的。
11 preserveAspectRatio="xMinYMid slice"
程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMid slice" > <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
效果如下
示意圖如下所示:
如上所示:xMin 的含義是:viewport(畫布)的x軸與viewBox(可視區)的x軸的最左側對齊,YMid的含義是:viewport(畫布)的Y軸與viewBox(可視區)的Y軸的中心對齊。所以如上所示, 但是由於寬度和高度都等比例放大了,所以結果會向上偏移了。
12. preserveAspectRatio="xMinYMax slice"
程式碼:
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200" preserveAspectRatio="xMinYMax slice" > <rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect> </svg>
執行效果如下:
其他的略..... 感覺slice這個屬性沒有理解透。今天先到這....