万丈高楼平地起,基础很重要。

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的更多相关文章

  1. SVG 入门——理解viewport,viewbox,preserveAspectRatio

    工欲善其事必先利其器,没有真正搞懂SVG里的viewport,viewbox, preserveAspectRatio这三个属性,就很容易遇到坑,最近写项目用到svg这三个属性被我一眼就略过 ,后来发 ...

  2. 理解SVG图片标签的viewport、viewBox、preserveAspectRatio缩放

    一.viewport 表示SVG可见区域的大小,或者可以想象成舞台大小,画布大小. <svg width="></svg> 上面的SVG代码定义了一个视区,宽500单 ...

  3. 理解SVG坐标系和变换:视窗,viewBox和preserveAspectRatio

    SVG元素不像HTML元素一样由CSS盒模型管理.这使得我们可以更加灵活定位和变换这些元素-也许一眼看上去不太直观.然而,一旦你理解了SVG坐标系和变换,操纵SVG会非常简单并且很有意义.本篇文章中我 ...

  4. 深入理解SVG坐标体系和transformations- viewport, viewBox,preserveAspectRatio

    本文翻译自blog: https://www.sarasoueidan.com/blog/svg-coordinate-systems/ SVG元素不像其他HTML元素一样受css盒子模型所制约.这个 ...

  5. 理解SVG坐标系统和变换: 建立新视窗

    在SVG绘制的任何一个时刻,你可以通过嵌套<svg>或者使用例如<symbol>的元素来建立新的viewport和用户坐标系.在这篇文章中,我们将看一下我们如何这样做,以及这样 ...

  6. 理解SVG坐标系统和变换: transform属性

    SVG元素可以通过缩放,移动,倾斜和旋转来变换-类似HTML元素使用CSS transform来变换.然而,当涉及到坐标系时这些变换所产生的影响必然有一定差别.在这篇文章中我们讨论SVG的transf ...

  7. 理解SVG中的 viewport,viewBox, preserveAspectRatio

    _ 阅读目录 一:理解viewport 二:理解viewBox 三:理解 preserveAspectRatio 回到顶部 一:理解viewport 该属性表示的是SVG可见区域的大小.或者也可以叫画 ...

  8. svg的viewport和viewbox

    svg中视区重要的概念 1. viewport  视口,相当于显示器屏幕 2. viewbox   视区,相当于在屏幕上截取一小块,放大到整个屏幕,就是特写的效果 3. preserveAspectR ...

  9. 深入理解 SVG 系列(一) —— SVG 基础

    来源:https://segmentfault.com/a/1190000015652209 本系列文章分为三个部分: 第一部分是 SVG 基础. 主要讲 SVG 的一些基础知识,包括 SVG 基本元 ...

随机推荐

  1. YYModel 源码解读(二)之NSObject+YYModel.h (4)

    接下来我们继续向下看 typedef struct { void *modelMeta; ///< _YYModelMeta void *model; ///< id (self) voi ...

  2. 读书笔记--SQL必知必会20--管理事务处理

    20.1 事务处理 使用事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性. 如果没有错误发生,整组语句提交给数据库表 ...

  3. PHP实现查询Memcache内存中的所有键与值

    使用Memcache时,我们可以用memcache提供的get方法,通过键查询到当前的数据,但是有时候需要查询内存中所有的键和值,这个时候可以使用下面的代码实现: <?php /** * Cre ...

  4. 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务

      上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...

  5. 绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来

    我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: ...

  6. ASP.NET Core 整合Autofac和Castle实现自动AOP拦截

    前言: 除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninject和Castle). 1.ASP ...

  7. RabbitMQ原理与相关操作(一)

    小编是菜鸟一枚,最近想试试MQ相关的技术,所以自己看了下RabbitMQ官网,试着写下自己的理解与操作的过程. 刚开始的第一篇,原理只介绍 生产者.消费者.队列,至于其他的内容,会在后续中陆续补齐. ...

  8. 说一说javascript跨域和jsonp

    同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规 ...

  9. 记录一次bug解决过程:else未补全导致数据泄露和代码优化

    一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...

  10. Consul的一个更新:服务端节点故障后重连

    研究了一段时间Consul,想写个攻略来着,但太赖了而且表达能力非正常人...今天发现HashiCorp果然接纳大众意见改了点东西.. 场景是: 假如Consul集群内有三个Server Node 时 ...