理解 SVG 中的 Viewport 和 ViewBox - 實做縮放(zoom)和拖曳(drag)效果
本文章同步刊載於 PJCHENder 前端網頁資源站
不同於以往將 SVG 視為一張圖案(ICON 或 LOGO)的概念,在這篇文章中,我們要試著將 SVG 視為一個畫布(Canvas),而我們可以透過滑鼠來直接對這個畫布像 Google Map 一樣進行拖曳和縮放。
要將 SVG 視為一個畫布,並實做出縮放或拖曳的功能,有許多對於 SVG 的基本概念是我們需要先瞭解的,就讓我們一步一步來瞭解。
註 1:在這篇文章中我們會把 SVG 視為一個畫布(Canvas)而不是去探究 SVG 中各個元素(例如,
<rect></rect><circle></circle>)。 註 2:在這篇文章中我們只考慮 viewport 和 viewBox 為等比例的情況。
最後實做出來的功能會像這樣子:實做 SVG 拖曳與縮放
瞭解 SVG 中的 Viewport 和 ViewBox
在 SVG 的世界中,空間的概念可以分成 Viewport 和 ViewBox 兩個部分。在這篇文章中,我會把它 Viewport 比喻作相框,ViewBox 比喻作相片。
Viewport 相對上比較好理解,就是相框的大小,也就是你的眼睛看得到的範圍,不管你的相片多大,你能看到的實際範圍就是相框的大小。在網頁中我們可以透過設定 viewport 來調整我們相框的大小。
ViewBox 則可以想成是這張照片的大小,如果相片的大小和相框(viewport)一樣大的時候,自然不會有什麼問題,你可以從相框中看一樣大的相片。可是,如果相片(viewbox)比起相框來得大或來得小時,這時候就會比較麻煩些,你會需要多去控制說這張相片應該要如何的排置在相框上,才能夠呈現出你想要呈現的東西,因此 ViewBox 中除了能夠控制的相片的大小之外,還能夠控制相片要如何擺放在相框中。
讓我們來瞭解一下 viewport 和 viewbox 的概念:
當 viewBox 等於 viewport 的情況(初始化的情況)
首先,我們可以直接在 SVG 元素上定義 viewport 的寬高,或者你也可以用 CSS 定義,基本上這個 DOM 元素的寬高就是 viewport 的寬高,也就是你相框的寬高。接著我們可以在 SVG 中定義我們的圖案內容,在這裡先用一隻鳥當作示範。
<svg id="svgElement" width="800" height="400">
<g><!-- 鳥的圖形 --></g>
</svg>
這時候便會得到如下的一個 viewport:

再來我們可以設定 viewBox , viewBox 的設定可以寫在 SVG 的標籤上,設定屬性包含 <min-x> <min-y> <width> <height> 這四個屬性,也就是 viewBox = '<min-x> <min-y> <width> <height>' 。
我們剛剛有提到,ViewBox 中除了能夠控制的相片的大小之外,還能夠控制相片要如何擺放在相框中,其中 <min-x> 和 <min-y> 就是在控制相片要如何擺放在相框中,而 <width> 和 <height> 則是相片的大小。
預設的情況下(沒有特別去設定 viewBox 的情況下)viewBox 的尺寸大小會和 viewport 一樣,因此當我們把鳥的相片放入 svg 後,他會自動填滿整個相框,兩個的大小會是一樣的,程式碼會像這 樣:
<svg id="svgElement" width="800" height="400" viewBox="0 0 800 400">
<g><!-- 鳥的圖形 --></g>
</svg>
相片會很完整的融入在相框當中

viewBox 初始化時尺寸大小會和 viewport 一樣