我们在绘制SVG图形的时候经常需要绘制一些箭头、点状线和虚线效果,虽然我们可以通过Adobe Illustrator和Inkscape等矢量图软件来直接生成这些图形,但是我们更应该了解如何手动来实现这些图形效果。
一条路径(path)的外观是由描边(stroke)属性和stroke-width
属性来控制的。stroke
属性用于控制线条的颜色,而stroke-width
属性则用于控制线条的宽度。
虚线(Dashes)
SVG的描边属性提供了一个stroke-dasharray属性来实现虚线的效果。stroke-dasharray
属性的值可以由1个或多个数值组成。第一个数代表虚线的长度,第二个数代表虚线之间的间隙的长度。不带单位的数值的会被解析为像素单位,你也可以使用任何在SVG中有效的长度单位。
如果stroke-dasharray
的值只有一个数,表示虚线的长度和虚线间的间隙相等,例如:
<svg viewBox="0 0 300 10"> <line x1="0" y1="0" x2="300" y2="0" stroke="black" stroke-width="10" stroke-dasharray="5" /> </svg>
上面的代码会得到下面的虚线效果:
我们也可以设置CSS样式来达到相同的效果。
<svg viewBox="0 0 300 10"> <style type="text/css"> line#simple { stroke: black; stroke-width: 5; stroke-dasharray: 5; } </style> <line id="simple" x1="0" y1="0" x2="300" y2="0" /> </svg>
如果stroke-dasharray
的值有2个数,那么第一个数代表虚线的长度,第二个数代表虚线之间的间隙的长度。例如:
<svg viewBox="0 0 300 10"> <line x1="0" y1="0" x2="300" y2="0" stroke="black" stroke-width="5" stroke-dasharray="5,10" /> </svg>
上面的代码会得到下面的虚线效果:间隙是虚线长度的2倍。
同样也可以通过CSS来实现它:
<svg viewBox="0 0 300 10"> <style type="text/css"> line#simple { stroke: black; stroke-width: 5; stroke-dasharray: 5, 10; } </style> <line id="simple" x1="0" y1="0" x2="300" y2="0" /> </svg>
如果stroke-dasharray
的值为奇数,例如3个,那么虚线会按这种指定的模式重复绘制。例如,如果指定的值是5,20,5
:
<svg viewBox="0 0 300 10"> <line x1="0" y1="0" x2="300" y2="0" stroke="black" stroke-width="5" stroke-dasharray="5,20,5" /> </svg>
上面的代码会得到下面的虚线效果:先绘制5像素的虚线,然后是20像素的间隙,最后是5像素的虚线。接着按照这个模式继续重复绘制。
stroke-dashoffset
stroke-dashoffset属性用于指定虚线的偏移距离。例如下面的例子:
<svg viewBox="0 0 300 10"> <style type="text/css"> line#simple { stroke: black; stroke-width: 5; stroke-dasharray: 5, 20, 5; stroke-dashoffset: 20; } </style> <line id="simple" x1="0" y1="0" x2="300" y2="0" /> </svg>
上面的代码会得到下面的虚线效果:这条虚线和上例中的虚线是同一条虚线,只不过它使用stroke-dashoffset
属性将它的开始位置移动了20像素。
描边动画
我们可以通过CSS来制作SVG的描边动画。如果stroke-dashoffset
属性的值和stroke-dasharray
的值相同,并且它们都等于路径的长度,此时,我们只需要实时改变stroke-dashoffset
的值,就可以制作出描边动画效果。
@keyframes strokeanim { to { stroke-dashoffset: 0; } } line#dashstart { stroke: hsl(260, 50%, 30%); stroke-width: 15; stroke-dasharray: 300; stroke-dashoffset: 300; animation: strokeanim 2s alternate infinite; }
Stroke的其它用法
在上面的例子中都是使用<line>
元素来作为例子。实际上,Stroke
可以使用在任何SVG基本图形中,包括矩形、多边形和路径等。例如下面的代码使用虚线来绘制一个矩形。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200"> <style type="text/css"> rect#strokedrect { stroke: hsl(260, 50%, 3%); fill: white; stroke-width: 7; stroke-dasharray: 10; } </style> <rect id="strokedrect" x="0" y="0" width="300" height="200" /> </svg>
得到的结果如下:
需要注意的是描边总是绘制在路径的中心点上。在上面的例子中我们看不出什么问题,这是因为SVG矩形和它的viewBox容器的大小相同,并且没有填充色。如果我们设置SVG矩形和viewBox的大小不一样,再给它一个填充色,就可以看到问题的所在了。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200"> <style type="text/css"> rect#strokedrect { stroke: hsl(260, 50%, 3%); fill: gray; stroke-width: 7; stroke-dasharray: 10; } </style> <rect id="strokedrect" x="20" y="20" width="260" height="160" /> </svg>
得到的结果如下:
到目前为止,SVG还不支持stroke的定位,例如没有“居内”、“居外”和“居中”的设置。但是在SVG2中提出了相关的内容。
同样,我们也可以为SVG矩形制作描边动画效果。例如:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200"> <style type="text/css"> @keyframes marchingants { to { stroke-dashoffset: 19; } } rect#strokedrect { stroke: hsl(260, 50%, 90%); fill: white; stroke-width: 7; stroke-dasharray: 10; animation: marchingants 1s forwards infinite linear; } </style> <rect id="strokedrect" x="0" y="0" width="300" height="200" /> </svg>