SVG系列教程:坐标系统
SVG其实相当于一块画板,然后在这块画板上绘图形,而每个画板都会有一个坐标系统。比如说画板的原始起点,绘制图形的起始点坐标,终点坐标等。这一切的一切都离开不坐标,而这些坐标就组成了一个坐标系统。在这篇文章的所要介绍就是SVG中一个关键知识点——SVG坐标。简单点理解SVG坐标就是屏幕坐标点(从技术上讲,最初的viewport坐标系统)与任何SVG元素相关联的坐标点系统(当前用户坐标系统)。例如,一个<svg>中使用<circle>绘制的一个圆,他就使用了一个标准的笛卡尔坐标系统(Cartesian Coordinate System)。

记忆中的坐标系统
记忆中的坐标系统(2D)就是有两根轴线(x轴和y轴),交织在一起,而他们这个交点被称为坐标原点(0,0)。沿水平方向左右延伸的这条轴,称之为水平轴(也就是x轴),而沿纵向上下延伸的这条轴,称之为垂直轴(也就是y轴)。原点沿x轴向右为正值,反之为负值;同样在y轴也是如此。如下图所示:

但在设计中,坐标系统原点一般都是在屏幕的左上角处。不仿来看看制作软件中的一张平面截图:

而浏览器中也有一个坐标系统,他和制作图软件中的长得非常相似,原点都在屏幕左上角处:

这似乎脱离今天要说的主题了一样,我们还是回到SVG的坐标系统中来吧。
Viewport
在Web页面开发中,Viewport严格来讲就是浏览器的窗口。他不是一个HTML的概念,也就无法通过CSS修改Viewport。对于桌面浏览器,Viewport其实就是浏览器的宽度高度,而在移动端设备浏览器中,Viewport就稍加复杂。(感兴趣的可以点击这里阅读)。
在SVG中也有一个Viewport,而这个viewport被视为SVG的可见区域大小,将其想象成画布或者画板大小。在<svg>元素中通过设置其width和height属性来控制SVG的viewport大小。其中width和hegiht的属性值可以直接是一个简单的数字,也可以指定具体的单位。如果没有指定单位,那么将会认其为“像素px”为单位。
| 单位 | 含义 |
|---|---|
| em | 相对于父元素的字体大小 |
| ex | 相对于小写字母"x"的高度 |
| px | 相对于屏幕分辨率而不是视窗大小:通常为1个点或1/72英寸 |
| in | inch, 表英寸 |
| cm | centimeter, 表厘米 |
| mm | millimeter, 表毫米 |
| pt | 1/72英寸 |
| pc | 12点活字,或1/12点 |
| % | 相对于父元素。正常情况下是通过属性定义自身或其他元素 |
其实,SVG中的Viewport还包含一些其他相关的知识,而这些知识对于使用SVG都是非常重要的,感兴趣可以看看@张鑫旭大写师的一篇相关教程《理解SVG的viewport,viewBox,preserveAspectRatio》。
SVG坐标系统
理解了一SVG的viewport之后,我们来深入了解SVG的从标系统。SVG的坐标系统分为三种类型:
- 最初坐标系统
- 嵌套坐标系统
- 转换坐标系统
接下来,我们一起来了解SVG这三种坐标系统。
最初坐标系统
SVG的最初坐标签系统和viewport的坐标系统是相同的,都是在左上角原点处,沿y轴向下和x轴向右延伸。也就是说,SVG的坐标系统类似于Viewport的坐标系统,原点(0,0)在左上角处,不管使用单位还是不使用单位,其都是沿y轴向下垂直延伸,沿x轴向右延伸。如下图所示:

假设你有一个SVG:
<svg width="300" height="300">
</svg>
那么这个SVG的大小是300*300,其是由坐标(0,0)、(300,0)、(300,300)和(0,300)组成的一个矩形画布:

这里没有设置具体的单位值,表示的就是SVG画布大小是300*300个单位,默认情况下就是px。
为了让大家更好理解SVG最初坐标,来看几个示例。
下面的示例,创建了一个300*300像素(px)的SVG,然后使用<rect>在<svg>中绘制了一个矩形,这个矩形的起始点是(20,20),其宽度是100px,高度是50px。如下:
<svg width="300" height="300">
<rect x="20" y="20" width="100" height="50" style="stroke: #f36; fill: rgba(123,123,23,.5);"/>
</svg>
效果如下:
即使SVG的Viewport没有设置具体的单位,<svg>中的图形元素(比如<rect>、<line>等)也可以设置具体的单位值,比如:
<svg width="300" height="300">
<rect x="20" y="20" width="50mm" height="50mm" style="stroke: #f36; fill: rgba(123,123,23,.5);"/>
</svg>
效果如下:
另外,<svg>设置了Viewport的具体单位,并不会影响坐标没有单位的子元素。比如下面的示例,<svg>的Viewport设置了单位为mm,但矩形<rect>绘制还是按像素的坐标在绘制。
<svg width="100mm" height="100mm">
<rect x="20" y="20" width="50" height="50" style="stroke: #f36; fill: rgba(123,123,23,.5);"/>
</svg>
效果如下:
嵌套坐标系统
在<svg>元素中可以嵌套<svg>元素。外面的<svg>创建一个Viewport和坐标系统,而且嵌套在里面的<svg>也可以创建一个Viewport和坐标系统。这种方式就是在大的画布中绘制一个小的画布,我们就可以使用这种技术实现下面的效果:
而不是先绘制矩形,然后绘制圆形,再调整圆形到指定的位置,我们只需采取以下步骤:
- 首先创建一个
<svg>,用于绘制外面的大画布 - 在外面的
<svg>里使用<rect>绘制一个蓝色矩形 - 在
<svg>中嵌套一个<svg>,并且给里面的<svg>设置适当的preserveAspectRatio属性 - 在里面的
<svg>中使用<circle>绘制一个圆
这个简单的示例典型向大家阐述了SVG中嵌套的坐标系统。接下来,花点时间来阐述这个过程:
首先使用<svg>创建了一个主画布,并且使用<circle>在这个画布中绘制了一个圆:
<svg width="600px" height="300px" viewBox="0 0 250 250">
<circle cx="35" cy="35" r="35" style="stroke: black; fill: none;"/>
</svg>
效果如下;
接下来使用<rect>在主画布<svg>中绘制了一个蓝色矩形:
<svg width="600px" height="300px" viewBox="0 0 250 250">
<circle cx="35" cy="35" r="35" style="stroke: black; fill: none;"/>
<rect x="150" y="50" width="200" height="100" style="stroke: blue; fill: none;"/>
</svg>
效果如下:
现在添加一个<svg>元素,并且交这个<svg>元素嵌套在前一个<svg>元素中,同时给其指定viewBox、width、height和preserveAspectRatio属性值。你还可以为其指定x和y属性值(如果不显式的声明x和y属性值,将默认其值为0)。从而生成一个新的Viewport。
<svg width="600px" height="300px" viewBox="0 0 250 250">
<circle cx="35" cy="35" r="35" style="stroke: black; fill: none;"/>
<rect x="150" y="50" width="200" height="100" style="stroke: blue;
fill: none;"/>
<svg x="150px" y="50px" width="200px" height="100px" viewBox="0 0 125 125" preserveAspectRatio="xMaxYMax meet">
</svg>
</svg>
效果如下:
从效果中看不到任何的变化,其实在上面的代码中,将内嵌的<svg>与<rect>重叠在一起。
建立这种嵌套的<svg>元素的新坐标,仅从视觉上并看不出任何的不一样,但它允许你添加新的元素,比如这个示例中,在里面添加一个<circle>,就能立马体会到其不一样的好处了:
<svg width="600px" height="300px" viewBox="0 0 250 250">
<circle cx="35" cy="35" r="35" style="stroke: black; fill: none;"/>
<rect x="150" y="50" width="200" height="100" style="stroke: blue;
fill: none;"/>
<svg x="150px" y="50px" width="200px" height="100px" viewBox="0 0 125 125" preserveAspectRatio="xMaxYMax meet">
<circle cx="35" cy="35" r="35" style="stroke: black; fill: rgba(0,0,0,.5);"/>
</svg>
</svg>
最终效果如下:
转换坐标系统
转换坐标系统比前面介绍的最初坐标系统,嵌套坐标系统要复杂的多,里面还涉及到数学矩阵相关知识,在这篇文章中暂不做这方面的阐述,在后面我们将会一篇专门的文章来介绍SVG的转换坐标系统。
总结
文章主要介绍了SVG的坐标系统相关知识,详细介绍了SVG中的最初坐标系统和嵌套坐标系统。其实除了这两个坐标系统之外还有一个转换坐标系统,而这个坐标系统在制作SVG相关动画效果起着相当关键作用。所以也是学习SVG知识必可不可缺的一部分。但在这篇文章并没有以过多的篇幅来阐述相关知识,因为后面将专门用一篇文章来阐述SVG中的变换坐标系统。
如需转载,烦请注明出处:http://www.w3cplus.com/html5/svg-coordinates.html




