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中的变换坐标系统。