图解SVG的核心概念

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

在SVG中,对于很多初学者或者使用SVG有一段时间的同学来说,有几个概念总是会相互混淆。比如,SVG的画布视窗(Viewport)ViewBox等。这几个概念对于学习或掌握SVG来说是非常必要的。在此我们一起来学习和了解这几个概念。

画布

SVG和Canvas类似,它也有一个画布的概念。SVG中的画布是一个无限区域,即x轴和y轴都可以无限延伸。好比Sketch中,新创建的一个文件,你可以在新创建Sketch设计软件中的可见区域或不可见区域绘制任何图形(在Sketch可以通过拖跩让不见区域到可见区域):

如果回到SVG中的话,那么<svg>标签就是一个画布,这个画布大小是无限的。

<svg></svg>

SVG的初始坐标

SVG也有一个初始坐标,这个坐标和我们所理解的Web坐标相似,都在屏幕的左上角。如果放到SVG画布中的话,这个坐标原点是在画布的正中间(即(0,0)位置),沿着x轴向右的水平方向为正值方向,沿着y轴向下的方向为正值方向:

我们可以在这个坐标系统中(SVG画布中)任意位置绘制想要的图形,比如:

视窗(Viewport)

SVG画布是可以无限延伸的,但我们的设备屏幕本身并不是无限长的,于是SVG的渲染输出是必须对应有限尺寸的可视区域。这个可视区域将它称为视窗,即Viewport。这个可视区域指的就是SVG的显示范围。我们可以把Viewport想成浏览器视窗。

我们通过视窗来看里面的内容。

在SVG中,也可以把视窗当作一个容器,即创建了一个<svg>标签就创建一个视窗。而这个视窗的大小可以通过<svg>widthheight属性来指定大小:

<!-- 创建一个800 x 600 个单位的Viewport -->
<svg width="800" height="600">
    <!-- SVG画布 -->
</svg>

注意,这里所说的一个单位指的是用户单位。比如上面示例中的800 x 600并不是我们所说的px单位,如果用户的坐标系统用的是cm作为单位,那么对应的是800cm x 600cm

画布 vs 视窗

简单地说,如果你使用<svg>标签就同时创建了一个SVG画布和一个视窗。这两个概念往往是很容易混淆的。因为它们两各自独立却又相互关联。因此,我们很有必要明白它们之间的关系。

为了更好的理解这两个抽象的概念,用生活中的一个实例来阐述。你可以把视窗想象成飞机上的窗户,把画布想象成窗外海阔天空的风景。坐在机舱的你只能透过窗户观看窗外的风景。

当然,SVG的画布和视窗并不是完全割裂的,它们之间有着一定的关联:

  • 每创建一个<svg>元素,就相当于创建了一个无穷大的画布,同时创建了一个有限区域的视窗
  • SVG的画布和视窗分别对应两个坐标系统,一个用户坐标系统(建立在SVG画布上的坐标系统),一个视窗坐标系统(建立在视窗上的坐标系统),这两个坐标系统默认是对齐的,它们的原点和坐标都是完全一致的,也就是说初始用户坐标系统的原点就位置视窗的左上角(也就是x轴正向向右,y轴正向向下)

SVG的viewBox

SVG中还有另一个概念,那就是viewBox的概念。同样拿生活中的示例来向大家阐述SVG中的viewBox。在坐飞机的时候,你可能会用手机透过飞机的窗户(Viewport)来拍摄窗外风景(SVG画布),那么这个相机有一定的可视区域,这个区域就类似于SVG中的viewBox

拿着手机你可以在窗口区域(Viewport)内移动,这个时候只有手机区域(摄像机镜头)才可见,而且随着你移动,它的可见区域会变动。换到SVG的<svg>标签中的话,它由四个参数来决定:

<svg viewBox="0 0 200 200">
</svg>

viewBox的值是:

viewBox = "<min-x> <min-y> width height"

其中<min-x><min-y>的值决定viewBox的左上角顶点坐标,widthheight则决定viewBox的区域大小。

如果拿到Sketch中来的话,整个绘制工作区相当于SVG的画布,我们可一定的可视区域当作是SVG的视窗,而它的“画板”工具可以看作是SVG的viewBox。只有在“画板”区域内的图形才能被看见:

SVG画布、视窗和viewBox的关系

我们用一个示例来描述SVG世界中画布视窗viewBox三者之间的关系。

简单地说,在SVG的世界中,底下有一张不限宽高的画布,好比上图中的浏览器可视区域,预设用px当单位,我们在这个SVG画布中绘制图形;接着上面有一层SVG视窗(Viewport),好比上图中的相框;接着再有一层viewBox,好比上图中的风景图(相片)。

正如前面提到的,SVG画布是无限大的(想象成上图中的浏览器可视区域可以不断扩展大小);SVG视窗是有一定大小的,比如上图中的相框大小(相框的宽和高决定了其大小),这也是你眼睛看得到的范围。也就是说,不管你的相片有多大(viewBox),你能看到的实际范围就是相框的大小。

viewBox则可以想成相片的大小,而这张相片可能:

  • 相片可能会比相框小
  • 相片可能会比相框大
  • 相片可能会和相框一样大

如果相片和相框一样大的时候,你可以在相框中看到完整的相片。可相片和相框大小不同时,就会相对麻烦一些,我们要控制相片在相框中的位置和大小,才能在相框中呈现你想要呈现的东西。可以使用<svg>viewBoxwidthheight来控制相片大小,使用<min-x><min-y>控制相片的位置。

视窗(相框)和viewBox(相片)相等

我们来看一个示例:

<svg width="800" height="400" viewBox="0 0 800 400">
    <image href="https://www.w3cplus.com/sites/default/files/blogs/2020/2008/svg-in-react-32.png" width="800" height="400" />
</svg>

示例中的<svg>widthheight创建了一个视窗(Viewport),它的大小是800 x 400,也就是相框的宽高。而viewBox属性创建了一个ViewBox。这个ViewBox除了能够控制相片大小之外,还能控制相片如何在相框中摆放,其中viewBox的前两个值<min-x> <min-y>(即0 0)就是控制相片要如何摆放在相框中,而<width> <height>则控制相片的大小。

预设的情况之下,ViewBox和Viewport大小一样,因此当我们把相片放到相框中,会自动填满相框:

视窗(相框)大于 viewBox(相片)

我们可以通过<svg>viewBox属性来调整ViewBox(相片)大小,这里有一个原则是,ViewBox会自动尽可能去填满整个Viewport。

<svg width="800" height="400" viewBox="0 0 400 200">
    <image href="https://www.w3cplus.com/sites/default/files/blogs/2020/2008/svg-in-react-32.png" width="800" height="400" />
</svg>

这个时候视窗大小是800 x 400,而ViewBox的大小是400 x 200。即ViewBox(相片)比视窗(相框)小,它会在原本相片上裁切一小块(ViewBox区域),接着把它调整到填满整个视窗。

我们用

剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/svg/svg-core-conception.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部