可缩放矢量图形的一大优势(除了它们可以被无限缩放而没有质量损失之外)是一旦你知道了基本的原理,无需打开绘图程序你就能很容易地手写出一些简单的形状。
只要很少的几行代码你就可以拥有你的自定义图标,而且你还很清楚每个图标是怎么组合出来的。当你创建自己的SVG时,你可以确保以最有效的方式来编写它们,并且当你在站点中使用它们时,你拥有最大的控制权。
在本教程中,我们将涵盖手写SVG的所有基本原理,但我不会用一个仅仅是丢出一系列相关形状和属性的文章来烦你们。相反,你们会通过实践来学习如何手写SVG,创建出本教程开头那张图片上所列的6个图标(在线示例)。在此过程中,你将会用到手写SVG所需的所有基本元素。说到那些基本元素,让我们快速地介绍一下他们每一个的情况。
这些是你即将创建的图标
基本的SVG元素你可以深入SVG复杂的细节,但这对我们即将创建的图标不是必须的。以下列表涵盖了我们将用到的构建块。
svg包裹并定义整个矢量图。svg标签之于矢量图就如同html标签之于一个web页面。line创建一条直线。polyline创建折线。ct创建矩形。ellipse创建圆和椭圆。polygon创建多边形。path通过指定点以及点和点之间的线来创建任意形状。defs定义一个可复用的图形。初始情况下defs里面的内容是不可见的。defs标签之于矢量图就如同head标签之于一个web页面。g将多种形状组合起来。将组合后的形状置于defs中可以让它能够被复用。symbol类似于一个组合,但是拥有一些额外的特性。通常被置于defs标签中便于复用。use获取在defs中定义的复用对象并在SVG中显示出来。当我们继续阅读并创建我们的图标时,我们将以上面所看到的元素列表的顺序进行。
起始文件在我们开始之前,从这个GitHub仓库取一份起始文件。你可以下载一个.zip格式的文件或者直接将这个仓库clone到本地。我们将从一个已经包含了一些基本的HTML和CSS的文件开始。这会给我们即将创建的SVG以一些样式,也会在页面上准备一些小网格。我们将会在这些网格上创建我们的图标,希望它能在你放置你的SVG时帮助你确定坐标。
x和y值概述在网站的二维平面上,用x代表横轴,y代表纵轴。每个坐标轴上的位置都用数字表示。使用递增的x值来让物体右移,使用递减的x值来让物体左移。同样地,使用递增的y值来让物体下移,使用递减的y值来让物体上移。
一个常用的表示某一点的x值和y值的简写是(x,y)。例如,一个在x轴上的值为10,在y轴上的值为50的点可以写成(10,50)。在本教程中,我将不时地使用这个简写形式。
注意到我们网格中的那两条最粗的线了吗?我们将SVG的左上角与那两条直线相交的地方对齐放置。因此,这个交点将在我们的SVG中代表x=0和y=0,即(0,0)的位置。
网格背景每条最细的网格线之间相距10px,中等粗细的线之间相距px。因此若我们想将一个物体从一个中等粗细的线向下移动到另一个中等粗细的线,我们只需把y轴上的值增加px。
如果这听起来仍然有点不清楚,不用担心,在我们进行创建SVG图标的实际操作时你就会明白了。
默认的SVG样式注意在初始的HTML文件中有一些内嵌的CSS设置了我们即将创建的图标的默认样式。
svg{stroke:#;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill:none;}
上述CSS设置了我们的图标是无填充的,粗细5px的黑色线条绘制,边角平滑。
1.设置SVG创建任何SVG的第一步是写下一个svg/svg元素。你所期望你的SVG显示的所有内容都必须放在这个标签内部。在这个元素上可以使用一些属性,但为了保持简单,我们只使用宽度和高度。
将下面的代码添加到你的HTML文档的body标签里去:
svgwidth=""height=""/svg
注意:在我们的起始文件中的CSS会将这个SVG向下和向右各偏移px,以此保证SVG的左上角被置于背景网格中两条最粗的直线的交点处。在本教程的CodePen演示中的值也可能会稍有不同——但可以随意地对它们进行操作。
.创建左对齐图标让我们从使用line元素创建这个左对齐图标开始,你会用到line元素的4个属性:
x1:起点的水平轴坐标y1:起点的竖直轴坐标x:终点的水平轴坐标y:终点的竖直轴坐标综上,你会使用属性x1和y1来设置直线的起点,使用属性x和y来设置直线的终点。
让我们创建我们的图标的第一条线,即顶部的那条。我们打算让线长45px,然而我们使用的5px粗细的笔画会在我们的线条外增加一些额外的像素。因此我们需要将线条向右下角偏移px以确保所有因stroke产生的额外像素都不会被剪掉。
基于上述原因,我们从x轴的坐标和y轴的坐标处开始我们的直线。我们可以用属性x1=""y1=""来设置线的起点为(,)。
我们打算让线长45px,所以在起点的x轴坐标值上加上45得到x的值为48。我们想让直线在水平轴上的相同位置结束,因此设置y等于,也就是与y1相等的值。通过属性x="48"y=""设置了线的终点(48,)。
这第一根线的完整代码看起来应该是这样的:
linex1=""y1=""x="48"y=""/line
查看你浏览器中的预览,你会看到一条长45px的圆润黑线。
现在我们可以继续给我们的图标添加接下来的三条线。我们打算最终画出四条线。第一和第三根线长45px,第二和第四根线长6px。我们还想要在每条线之间有16px的垂直间距。
我们可以通过如下的代码得到这个图标:
linex1=""y1=""x="48"y=""/linelinex1=""y1="19"x="65"y="19"/linelinex1=""y1="5"x="48"y="5"/linelinex1=""y1="51"x="65"y="51"/line
注意:每条线的y值以16px递增来创建所需的垂直间距。
再看一看你的浏览器预览,你应该看到所有的四条线。你也可以直接在下面的codepen中编辑SVG:
代码详情:codepen.io/new4/在我们继续之前先注释掉你的图标有了这些代码,你的第一个图标就已经完成了。我们已经准备好继续去创建下一个图标了,我们想在网格的相同位置上创建这个图标,但现在左对齐图标占着这个位置。因此,现在需要注释掉它的代码来清理空间。稍后当我们将图标转换为可重用部件时,我们会回过头来恢复被注释掉的代码。
你需要对我们之后创建的每一个图标做同样的事情,即在完成创建之后将其注释掉。出于这个原因,在每个图标的代码之上添加一个小提示或许是个不错的注意,这样在之后回顾的时候你就知道哪个是哪个了。
.创建一个插入图标对于这个图标,让我们使用直线line元素衍生而来的折线元素:即polyline。我们将会使用它来创建一个指向右方的插入符。
polyline元素只有一个属性:points。在这里你会使用一对对的数字来设置一系列的点。点和点之间的线段会自动绘制出来。数值对就简单地一个接一个的被写在点属性里。可以使用逗号分隔,但这不是必须的。为了便于阅读,你可能还想在代码中将每一对值写成一行。
我们会在上一个图标的起始点处开始我们的插入图标,那就是(,),这确保了我们的笔画和线的端头不会被剪掉。我们想让第二个点向右移动,并向下移5px,那么我们把它设为(0,8)。我们的第三个点应该与第一个点垂直对齐,同时再向下移动5px,所以它应被设为(,5)。
你可以把这些点添加到polyline的points属性中去,如下:
polylinepoints=""/polyline
如果你想要更简洁的代码,你也可以把上面的代码写成:
polylinepoints=",08,5"/polyline
或者
polylinepoints=""/polyline
看一看你的浏览器预览,你会看到你的插入图标的显示:另一个图标就这样完成了!
代码详情:codepen.io/new4/同样地,在进入下一个图标之前先注释掉当前这个图标,并给它加上一个能让你知道它是什么图标的小提示。
4.创建一个浏览器图标现在我们有了线条,让我们从矩形(ct)开始创建一些形状。我们将把它与一些line结合起来创建一个浏览器图标。长方形和正方形可以通过ct元素来创建。ct有4个需要提供值的属性:
x:左上角的x轴坐标值y:左上角的y轴坐标值width:矩形的宽度height:矩形的高度注意:你也可以使用属性rx和ry来指定矩形的圆角半径。
我们要创建一个矩形,它的左上角有px的偏移量,同样是为了避免描边的截断,所以我们会用到x=""y=""的属性值。我们希望它是宽80px,高60px的,所以我们用到width="80"height="60"的属性值。
因此我们完整的矩形代码就应该是:
ctx=""y=""width="80"height="60"/ct
保存代码,到浏览器里面进行预览。你应该看到一个整洁的小矩形。
现在我们所要做的就是在顶部添加一条水平线,还有在靠近左上角的地方加上一条竖线,就像你在本节开始时所看到图像中的那样。我们将使用与之前绘制线段相同的过程,完整的浏览器图标代码看起来应该是这样的:
ctx=""y=""width="80"height="60"/ctlinex1=""y1="19"x="8"y="19"/linelinex1="0"y1=""x="0"y="17"/line
花点时间查看一下这两条线段的属性所提供的坐标,你可以稍微改变一下它们的值来看看它们在这个图标中是如何工作的。
代码详情:codepen.io/new4/5.创建一个警示图标现在我们可以控制矩形的创建,我们再试试使用ellipse。我们将使用两个ellipse以及一个line来创建这个警示的图标。
类似于矩形,ellipse元素也需要4个属性,然而这些属性和矩形的不同。我们使用的是水平和竖直半径而不是宽度和高度,同样地,我们通过中心而不是通过指定左上角来进行定位。
cx:中心位置在x轴上的坐标cy:中心位置在y轴上的坐标rx:沿x轴向的半径,也就是它会把图形分割成上下两部分ry:沿y轴向的半径,也就是它会把图形分割成左右两部分我们想要一个宽80px高80px的正圆,这意味着在两个轴上它的半径均为40px。我们用rx="40"ry="40"来设置这个值。
我们还想要这个圆处于与图上那两条最粗的线平齐的位置。假定我们的圆宽高均是80px,那么放置圆心的位置就是40px。同时为了避免图标被截断,需要px的偏移量,那么圆的中心点就在两轴的4px处。我们用属性cx="4"cy="4"来设定这个值。
将这些设定的属性值放在一起,就得到如下代码:
ellipsecx="4"cy="4"rx="40"ry="40"/ellipse
查看你的浏览器预览,现在在你的页面上应该能看到一个圆。
现在我们要添加第二个圆,创建感叹号底部的那个点。我们将以同样的方式创建它,唯一的区别是我们将使用内联样式来设置黑色的填充:
ellipsestyle="fill:black;"cx="4"cy="65"rx="5"ry="5"/ellipse
最后,我们只需要添加感叹号另外的线段部分。同样地,我们使用的技术与我们之前创建线段的一样,唯一的区别是我们将使用内联风格来将笔画的宽度从5px增加到8px。警示图标的完整代码:codepen.io/new4/6.创建一个播放图标现在我们已经有一些如矩形和椭圆形这样外形相对固定的形状,我们准备使用polygon元素来生成我们自己的形状。从八边形到五角星,我们可以用这个元素创建出我们想要的多边形。不过,我们现在就把事情弄清楚并创建一个三角形。我们将把它与一个ellipse元素组合在一起来创建一个播放图标。
polygon元素和polyline元素几乎一样。他们都只有一个points属性,采用一对对的值的形式来设置每一个点从而组成一个形状。不同之处在于,折线polyline不是闭合的而多边形polygon是自动闭合的。
让我们从下面这个圆开始,我们的多边形会放在它里面。我们使用的圆与我们在警告图标里面使用的相同:
ellipsecx="4"cy="4"rx="40"ry="40"/ellipse
现在我们来创建多边形。我们将会放置三个点,这些点之间会自动生成线段来创建一个三角形。点将是(5,),(60,4)和(5,6)。如此,我们的多边形代码将会是:
polygonpoints="5,,56"/
播放图标的完整代码:codepen.io/new4/7.创建一个下载图标现在,我们将学习最复杂的,但同时也是最灵活的生成SVG图形的方法,即path元素。创建一个路径有点像创建一个多边形,每次仅需将你的形状的一部分展示出来。然而,在路径中你直接创建每一个点,自定义每一条线,你还可以选择在点之间创建曲线而不是直线。
路径可以用来创建任何东西,但如果超出一定程度的复杂性之后,你最好还是使用矢量设计应用程序,而不是手写代码。出于这个原因,我们将重点