理解SVG的viewport,viewBox,preserveAspectRatio
2015-10-01 15:29
661 查看
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点 |
% | 相对于父元素。正常情况下是通过属性定义自身或其他元素 |
<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属性的值为空格分隔的两个值组合而成。例如,上面的
xMidYMid和
meet.
第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是大写。 |
x,
y自由合体就可以了,如:
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, 高
200.
x横轴比例是
2,
y纵轴比例是
1.
meet的作用是让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%)。
② 如果是
slice,
slice本身就有剪切的意思。代码如下:
<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的
width是
400. 显然,要想最大化充满,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,你是不可能在一种状态下同时看到
x,
y方向上的位移的。因为总会有一个方向是充满viewport的。
结束语
本文是几乎没有个人情绪,个人吐槽的一篇基础技术文章,以满足不同群体的胃口。行文仓促,错误难免,欢迎纠错。欢迎交流。
行文参考:SVG Viewport and View Box
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4323
一个全面的例子,可以下来自己在结合文章在细细体验一下:如下
<!DOCTYPE html> <html> <head> <title>ViewBox 使用演示</title> <style> body { background: #eee; } svg { position: absolute; border: 1px solid green; width: 300px; height: 200px; left: 50%; top: 50%; margin-top: -100px; margin-left: -150px; background: white; } input[type=number] { width: 50px; } </style> </head> <body> <h1>ViewBox 演示</h1> <form id="form"> <fieldset> <legend>viewBox</legend> <label>x: <input id="vx" type="number" value="0"></label> <label>y: <input id="vy" type="number" value="0"></label> <label>width: <input id="vw" type="number" value="300"></label> <label>height: <input id="vh" type="number" value="200"></label> </fieldset> <fieldset> <legend>preserveAspectRatio</legend> <label>align: <select id="align"> <option value="none">none</option> <option value="xMinYMin">xMinYMin</option> <option value="xMidYMin">xMidYMin</option> <option value="xMaxYMin">xMaxYMin</option> <option value="xMinYMid">xMinYMid</option> <option value="xMidYMid" selected>xMidYMid</option> <option value="xMaxYMid">xMaxYMid</option> <option value="xMinYMax">xMinYMax</option> <option value="xMidYMax">xMidYMax</option> <option value="xMaxYMax">xMaxYMax</option> </select></label> <label>meetOrSlice: <select id="meetOrSlice"> <option value="meet">meet</option> <option value="slice">slice</option> </select></label> </fieldset> </form> <p> <svg id="svg" xmlns="http://www.w3.org/2000/svg"> <!--Face--> <circle cx="100" cy="100" r="90" fill="#39F" /> <!--Eyes--> <circle cx="70" cy="80" r="20" fill="white" /> <circle cx="130" cy="80" r="20" fill="white" /> <circle cx="65" cy="75" r="10" fill="black" /> <circle cx="125" cy="75" r="10" fill="black"/> <!--Smile--> <path d="M 50 140 A 60 60 0 0 0 150 140" stroke="white" stroke-width="3" fill="none" /> <rect id="viewBoxIndicator" stroke="red" stroke-width="3.5" fill="none" /> </svg> </p> <script> function update() { var viewBox = [vx.value, vy.value, vw.value, vh.value].join(' '); var preserveAspectRatio = [align.value, meetOrSlice.value].join(' '); svg.setAttribute('viewBox', viewBox); svg.setAttribute('preserveAspectRatio', preserveAspectRatio); var rect = viewBoxIndicator; rect.setAttribute('x', vx.value); rect.setAttribute('y', vy.value); rect.setAttribute('width', vw.value); rect.setAttribute('height', vh.value); } form.addEventListener('input', update); update(); </script> </body> </html>
相关文章推荐
- 解析ASP.NET Mvc开发之EF延迟加载
- 再谈ASP.NET第七 - 跨应用、跨服务器的表单验证
- ASP.NET动态网站制作(5)-- 标签语义化及知识补充
- ASP.NET动态网站制作(4)--css(3)
- asp.net web forms page life cycle
- ASP.NET - cookie
- asp.net iis7 提示:在多字节的目标代码页中,没有此 Unicode 字符可以映射到的字符 错误的解决方案
- ASP.NET 5 和Entity Framework 7公告仓库
- AspectJ的简单使用
- ASP 页的执行造成响应缓冲区超过其配置限制
- asp.net TreeView 的使用
- asp.net TreeView 的使用
- ASP.NET\ASP.NET MVC表单提交遇到的问题结论
- ASP.NET内置对象一
- ASP.NET Web API实现微信公众平台开发(三)自定义菜单
- ASP.NET Identity V2
- Asp.Net发送ICQ信息
- »Spring 之AOP AspectJ切入点语法详解(最全了,不需要再去其他地找了)
- ASP.NET动态网站制作(3)--css(2)
- SVG小记——viewport,viewBox,preserveAspectRatio