我们在 《初识 svg 的 viewBox 属性》 中已经初步了解到 viewBox 属性能将svg画布内的图形进行zoom操作,即放大或缩小图形。本讲,我们将深入了解 viewBox 是什么、具体怎么工作。
svg画布的 width 和 height 属性 定义了画布的大小,svg 也有自己缺省的 width 和 height 值,300*150。宽高尺寸构成了整个画布的可视区域,它是一个矩形,所有的绘画内容就在它上面绘制。以下代码,定义了 200*200 的画布,并在其上绘制一个矩形和一个圆,矩形从 {0,0} 坐标开始绘制,宽高均为 100,圆的圆心在 {10,10} 坐标处,半径为 10。
代码:
<svg width="200" height="200">
<rect x="0" y="0" width="100" height="100" fill="green" />
<circle cx="10" cy="10" r="10" fill="red" />
</svg>
效果(我们在CSS里统一定义了 svg 的灰色边框):
灰色边框框定的矩形区域就是svg画布,它有一个术语叫 viewport,即视口。而我们已经知道名称的svg属性 viewBox 它叫视区,它用来定义svg画布的用户空间(user space),该空间即视区相当于望远镜,对着svg画布进行“遥摄”,以“观赏”一定区域的内容。viewBox 需要四个参数,min-x,min-y,width,height,各值用空格或小角逗号隔开:
viewBox="0 0 100 100" 或者 viewBox="0,0,100,100"
这是定义了视区区域为,从 {0,0} 坐标处开始,宽高为 100*100。viewBox 属性是可以缺省的,缺省时,它从 {0,0} 开始,取 svg 的宽高尺寸为 视区的 width 和 height 值,相当于望远镜所看到的的尺寸正好与svg画布尺寸相重合。viewBox 的宽高可以小于 svg 的宽高,试看代码:
<svg width="200" height="200" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="green" />
<circle cx="10" cy="10" r="10" fill="red" />
</svg>
效果会怎么样?请看:
这个结果不好理解吧?事实上,viewBox 属性一直令人困惑!
作为视区(viewBox),它定义的是用户空间(user space),viewBox 属性实际上是将 svg 画布上画好的图案重新规划,viewBox="0 0 100 100" 表示,从 {0,0} 开始对画布内原始图案进行“遥摄”,取 svg 上的 100*100 的图案,映射到整个画布中(就是望远镜所看到的的区域)。为了证实这一点,我们先把 viewBox 属性拿掉,再添加一个蓝色的圆,其圆心就在矩形的右下角:
<svg width="200" height="200">
<rect x="0" y="0" width="100" height="100" fill="green" />
<circle cx="10" cy="10" r="10" fill="red" />
<circle cx="100" cy="100" r="10" fill="blue" />
</svg>
结果是酱紫:
现在,我们加上 viewBox 属性:
<svg width="200" height="200" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="green" />
<circle cx="10" cy="10" r="10" fill="red" />
<circle cx="100" cy="100" r="10" fill="blue" />
</svg>
现在看看效果是不是正好是把上面的矩形区域放大了一倍:
这里换个方式解释一下 viewBox 的工作机制:viewBox 属性,定义从 min-x、min-y 开始,在 svg 原始画布上取 viewBox 的 width 和 height 区域,将这个区域的内容重新映射到整个画布,从而全新改变了画布的样貌。
viewBox 的 width 和 height 还可以大于 svg 设定的 width 和 height,试看以下代码和效果:
<svg width="200" height="200" viewBox="0 0 400 400">
<rect x="0" y="0" width="100" height="100" fill="green" />
<circle cx="10" cy="10" r="10" fill="red" />
<circle cx="100" cy="100" r="10" fill="blue" />
</svg>
可以看到,矩形和圆都缩小了一半!这是因为,viewBox 从 {0,0} 处开始,取画布上的 400*400 的区域重新映射到画布上。画布实际尺寸只有 200*200 的尺寸,viewBox 多出的部分是画布以外的,是空白的,但不管怎样,就按这个 400*400 的尺寸完整映射到画布中,这个 400*400 的区域就按比例缩小自身,然后完整映射给 200*200 的画布。注意观察右下角的蓝色圆,因为它的整体在 400*400 区域内,所以圆是完整的,不像前例的圆四分之三不在 100*100 区域内从而被无情切走。
说明:上面所举示例,viewBox 的 宽高 和 svg 的宽高都是成比例的,若比例不同,情况会更为复杂,这里先不表。