理解SVG的viewport,viewBox,preserveAspectRatio

來源:互聯網
上載者:User

標籤:

萬丈高樓平地起,基礎很重要。

viewport

表示SVG可見地區的大小,或者可以想象成舞台大小,畫布大小。

<svg width="500" height="300"></svg>

上面的SVG代碼定義了一個視區,寬500單位,高300單位。

注意這裡的措辭是“單位”,不是“像素”。雖然說,width/height如果是純數字,使用的就是“像素”作為單位的。

也就是說,上面SVG的視區大小就是500px * 300px.

當然,故弄“單位”這個措辭,潛台詞就是你可以使用其他類型的單位,涵蓋常見CSS單位:

單位 含義
em 相對於父元素的字型大小
ex 相對於小寫字母"x"的高度
px 相對於螢幕解析度而不是視窗大小:通常為1個點或1/72英寸
in inch, 表英寸
cm centimeter, 表厘米
mm millimeter, 表毫米
pt 1/72英寸
pc 12點活字,或1/12點
% 相對於父元素。正常情況下是通過屬性定義自身或其他元素

除了SVG本身,其他一些元素,例如<rect>width/height屬性也可以使用上面的這些單位,也是預設單位是像素。

viewBox屬性

這個是本文的重點,也是痛點。

先看一個活蹦亂跳的例子,如下HTML代碼:

<svg width="400" height="300" viewBox="0,0,40,30" style="border:1px solid #cd0000;">    <rect x="10" y="5" width="20" height="15" fill="#cd0000"/></svg>

結果如下:

或者親自圍觀demo

 

 

如果不看viewBox, 你一定會覺得詫異——SVG尺寸明明有400*300像素,而小小的<rect>大小隻有其1/20,但是顯示出來的卻佔據了半壁江山!不科學啊!

OK, 之所以小小矩形大顯神威就是這裡的viewBox起了推波助瀾的作用。

viewBox值有4個數字:

viewBox="x, y, width, height"  // x:左上方橫座標,y:左上方縱座標,width:寬度,height:高度

viewBox顧名思意是“視區盒子”的意思,好比在說:“SVG啊,要不你就讓我鋪滿你吧~”

更形象的解釋就是:SVG就像是我們的顯示器螢幕,viewBox就是截屏工具選中的那個框框,最終的呈現就是把框框中的截屏內容再次在顯示器中全螢幕顯示!

更直觀的解釋:
1. 如果沒有viewBox, 應該是長這樣的:

 

<rect>大小隻有整個SVG舞台的1/20.

2. viewBox="0,0,40,30"相當於在SVG上圈了左上方所示的一個框框:

 

 

 

3. 然後把這個框框,連同框框裡的小矩形一起放大到整個SVG大小(如下gif):

 

 

 

到手裡的才是自己的,您可以狠狠地點擊這裡:SVG viewBox屬性原理分步示範demo

 

 

preserveAspectRatio

上面的例子,SVG的寬高比正好和viewBox的寬高比是一樣的,都是4:3. 顯然,實際應用viewBox不可能一直跟viewport穿同一條開襠褲。此時,就需要preserveAspectRatio出馬了,此屬性也是應用在<svg>元素上,且作用的對象都是viewBox

先看下豬是怎麼跑的:

preserveAspectRatio="xMidYMid meet"

下面我們來吃豬肉。

preserveAspectRatio屬性的值為空白格分隔的兩個值組合而成。例如,上面的xMidYMidmeet.

第1個值表示,viewBox如何與SVG viewport對齊;第2個值表示,如何維持高寬比(如果有)。

其中,第1個值又是由兩部分組成的。前半部分表示x方向對齊,後半部分表示y方向對齊。家族成員如下:

含義
xMin viewport和viewBox左邊對齊
xMid viewport和viewBox x軸中心對齊
xMax viewport和viewBox右邊對齊
YMin viewport和viewBox上邊緣對齊。注意Y是大寫。
YMid viewport和viewBox y軸中心點對齊。注意Y是大寫。
YMax viewport和viewBox下邊緣對齊。注意Y是大寫。

xy自由合體就可以了,如:

xMaxYMax
xMidYMid

親愛的小夥伴,看出啥意思沒?

噔噔蹬蹬,沒錯,就是組合的意思:“右-下”和“中-中”對齊。恭喜你此處的知識點學習順利畢業!

preserveAspectRatio屬性第2部分的值支援下面3個:

含義
meet 保持縱橫比縮放viewBox適應viewport,受
slice 保持縱橫比同時比例小的方向放大填滿viewport,攻
none 扭曲縱橫比以充分適應viewport,變態

現在急需一個活生生的例子,讓大家感受下這三個值的表現。  

您可以狠狠地點擊這裡:meet,slice,none功能示範demo

首先,看下SVG代碼:

<svg width="400" height="200" viewBox="0 0 200 200" style="border:1px solid #cd0000;">    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/></svg>

截取SVG左邊一半(200正好寬度400的一般)作為視區,裡面有個150*150的紅色矩形。

預設展示如下:

 

 

如果我估計沒錯,預設應該是"xMidYmid meet"效果。

① 如果是meet效果,代碼如下:

<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid #cd0000;">    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/></svg>

效果如下:

 

 

表現原理為:SVG寬400, 高200,viewBox寬200, 高200x橫軸比例是2y縱軸比例是1meet的作用是讓viewBox等比例的同時,完全在SVG的viewport中顯示。這裡,最小比例是縱向的1,所以,實際上viewBox並沒有任何的縮放。

我們只要對viewBox屬性值做一點小小的修改(200→300),就可以感受到縮放了:

<svg width="400" height="200" viewBox="0 0 200 300" preserveAspectRatio="xMinYMin meet" style="border:1px solid #cd0000;">    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/></svg>

此時的顯示效果為:

 

 

改成300後,viewBox的高度就比viewport的200高,所以,viewBox要想完全適應viewport,就要進行縮放,所以,我們可以上到上面的矩形面積變小了,就是因為縮放的結果(縮放了200/300, 差不多原來的66.7%)。

 如果是sliceslice本身就有剪下的意思。代碼如下:

<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin slice" style="border:1px solid #cd0000;">    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/></svg>

效果:

 

 

slice也是要保持viewBox的縱橫比的,不過,其作用是盡量填滿viewport. 同樣,這裡viewBox寬度200,SVG的width400. 顯然,要想最大化充滿,viewBox的寬度就需要擴大為原來的兩倍。於是,就有了viewBox放大兩倍後的效果。由於viewBox部分地區超出了viewport, 視區之外內容是不可見的,於是就出現了slice所表意的“剪下”效果。

 如果是none, 則表示不關心比例,viewBox直接展開到最大填滿viewport.

<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin none" style="border:1px solid #cd0000;">    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/></svg>

 

原本好好的一個正方形,現在因為viewBox的展開,變成了一個寬高2:1的矩形了。

 

viewBox的對齊  

千言萬語不如一個可以自己動手體驗的demo實在,您可以狠狠地點擊這裡:viewBox的對齊各個名稱表現感受demo

截兩張圖給大家瞅瞅:

無論是meet還是slice,你是不可能在一種狀態下同時看到xy方向上的位移的。因為總會有一個方向是充滿viewport的。

結束語

本文是幾乎沒有個人情緒,個人吐槽的一篇基礎技術文章,以滿足不同群體的胃口。

行文倉促,錯誤難免,歡迎錯誤修正。歡迎交流。

 

原文http://www.zhangxinxu.com/wordpress/2014/08/svg-viewport-viewbox-preserveaspectratio/

理解SVG的viewport,viewBox,preserveAspectRatio

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.