如何用 SVG 画图

如何用 SVG 画图

Chris Yue No Comment
Posts

现实世界画一张图,你需要一张『画布』。广义的『画布』,可以是一张 A4 白纸,一面墙,一张布,一块黑板;另外你还需要笔,广义的笔可以是粉笔,可以是木炭。到了现代,画笔也可以是 iPad,而笔则是你的手指。

SVG 作为一种计算机文件格式,它倾向于使用各种数字去描述你的画笔和画笔。画布在 SVG 的世界,叫做 Canvas。在开始画图之前,你需要做一些准备工作,第一步便是告诉计算机,你需要多大的一张画布。

画布的大小,便是通过两个数字来描述的。同我们小学的时候学的二维坐标一样,这两个数字描述了 Canvas 的长度和宽度,而它的单位是像素,即显示器上能显示的最小单位,这里先不管像素的大小,后面会让你们感受到。

如同我们可以用英文或者中文描述一张画布的大小和底色,计算机也一样,可以由各种规定好的描述方式去告诉计算机画布的信息。而 SVG 格式用的是 XML 格式。

如同我前一篇文章里所说,学习更多的是模仿,这里也不细说 XML 是怎么样的一种格式,XML 本身就是一种容易理解和模仿的文件格式。我们直接看如何定义画布的例子即可。我们可以使用任何一种文本编辑器,比如 Windows 自带的记事本,输入以下内容,然后保存在任何一个你想保存的地方,比如『我的文档』里,但要记住,SVG 文件的扩展名必须是 .svg,比如叫 my.svg

SVG 是一种图片格式,但它又是文本编辑的,所以也是一种文本格式。就如不同的人看待某个客观的事物会因不同的角度,得到不同的感受一样,计算机里的软件(或者说 App)看待同一个文件也可能因『角度』不同,而有不同的显示。比如『记事本』看 SVG 就是一堆文字,而『谷歌浏览器』看 SVG 就是图片。

当然『谷歌浏览器』只是举一个例子,现在的浏览器都支持显示 SVG 文件。一般现在的软件要打开某个文件,都是将要打开的文件往软件界面上一拖,甚至是往软件图标上一拖就行了。

不出意外,你将在浏览器里正常打开刚刚创建的 SVG 文件,但什么都看不到。毕竟,目前我们只是定义了画布。而画布底色又是透明的,看不到很正常。

我们现在可以在画布上画点东西,比如我们可以将整个画布画满黑色,来充当画布底色:

注意上面的内容,我们只增加了第二行的代码。其他都没变。

刷新浏览器,应该会发现出现了一块黑色正方形。

因代码大都是英文描述的,我建议大家平时多学习英文(关于如何学习英文,我之后也会分享给大家),可更容易理解代码的意思。在代码里,英文好的估计已经发现第一行,定义了宽(width)为 200,高(height)为 200,虽然没有单位,但前面有提过,单位为『像素』。而最后的 xmlns,我建议大家先忽略它,因为在现在这个阶段,它并不重要,只要记住必须得写它就行了。到了合适的时候,我也会跟大家解释它到底代表了什么意思,有什么作用。

第二行,英文好的一看就知道是在描述四边形(rect),并且宽和高都是 100%,猜也能猜到,就是跟画布一样大小,并且,用了黑色作为填充色(fill="black")。

虽然我们对一个像素到底有大没有什么直观感受,但是 200 x 200 个像素的大小我们已经看到了,应该还是能间接感觉到的吧?

有了画布之后我们可以尝试画一些简单的图形。三角形应该是最简单的平面图形了,依然先给出例子:

刷新浏览器后应该能看到下面的图片

我们刚才的代码,也就只增加了第三行。英文好的应该能看出来,我们画了路径(path),但 d 描述的是啥意思,不解释可能就有点晕了(当然也不是不能猜出来,大家可以尝试猜一下再往下看)。最后的填充色写法跟 rect 一样,这就不用多说了,而且估计大家自己也找到某种规律:要填充一个图形,很有可能都是用的 fill 来实现。

这里来说说 d ,虽然我也不是很情况为什么 d 叫 d,我猜测可能是 direction 也就是『指令』的意思。d 后面的第一个 M,是 Move to 的意思,M 100 140 表示把画笔先移动到 100, 140 这个坐标点上,也就是三角行最下方的端点位置。不用我多说我想大家也都知道 SVG 的坐标系是一种什么样的描述方式了。接下来,L 表示 Line to 的意思,L 40 70 也就是画根线到 40, 70 这个坐标上。说到这,我觉得最后的 L 160 70 应该也没有解释的必要了。

似乎有了 path 之后,我们就可以画各种各样的多边形了,但曲线呢?几何好点的可能会想说,可以用无限逼近曲线的方式画多边形,理论上是可以这样做的,就是这工作量太大了。假如我们想把刚刚的三角形改成红心,想想得有多少个点要去写呢?

还好 d 支持的指令,其实也是包含曲线指令的。对于画红心的需求,见下面的代码:

生成的图片如下:

当然,这个红心画的有点恶心,不过不要在意这些细节……

上面的代码,只是把 path 的 d 的最后一个指令 L 160 70,改成了 C 60 30, 80 30, 100 70 C 120 30, 140 30, 160 70,C 是 Cubic Bezier Curve 的意思。至于 C 是如何去描述曲线的,这里我不打算说,因为无论如何描述,我都觉得没有直接通过丰富的例子去感受来的爽快。红心是一个对称图形,上面的指令虽然看着复杂,但能看出是以横坐标 100 为中轴左右对称的。为了方便大家感受,我先把右边的曲线,也就是最后的 C 120 30, 140 30, 160 70,改回用直线来描述,怎么改呢,就是把 C 指令提到的 3 个点,都改成 L 指令变成 L 120 30 L 140 30 L 160 70

得到下方的图片:

这个时候同时修改中轴左右两边对称的点的坐标(当然,保持对称),感受一下曲线是如何变化的。

其实上面说的用 path 来画图的方式,已经是 SVG 里最灵活但又最麻烦的方式了,然而,我相信只要知道用 path 怎么画图,其他的图形了解起来那就太轻松了,可以说都是些『快捷方式』,比如上面提到过的 rect。另外就 path 本身而言,M 指令,L 指令,C 指令也都是最灵活却又是最麻烦的,一些其他的指令,比如 H (Horizontal,横向画线到某个横座标)V(Vertical,纵向画线到某个纵坐标),Q(Quadratic curve),那也都是『快捷方式』,看文档就知道怎么用了。

扩展阅读:MDN 的 SVG 教程,建议不用从头看,直接从 Basic shapes 一章看起,示例丰富。

最后,建议大家自己多试试,比如将上面的红心改得更圆润,甚至你可以尝试使用文档提到的渐变,让红心有些 3D 的感觉。总之还是那句话,有明确的目标(并且是自认为有意义和价值的目标),能自然促使你学到更多。

如何用 SVG 画图 by Chris Yue is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

微信赞赏码

文章可赞,扫码赏饭!
天使投赏人

发表评论

34 + = 41