暗黑模式
描边(stroke)
前端教程SVG
fill
属性用于填充图形背景,stroke
属性用于描边(可以将其想象为画笔的颜色),前面的课程中我们仅仅使用了 stroke
的基本用法,本节我们详细讲解 stroke
的各种用法。
TIP
fill
的大部分语法,同样适用于 stroke
。
基本语法
html
<svg>
<xx stroke="colorKeyword" /> <!-- 颜色关键字 -->
<xx stroke="customColor" /> <!-- 自定义关键字 -->
<xx stroke="rgb(r,g,b)" /> <!-- 颜色函数 -->
<xx stroke="rgba(r,g,b,a)" /> <!-- 颜色函数 -->
<xx stroke="hsl(h,s,l)" /> <!-- 颜色函数 -->
<xx stroke="hsla(h,s,l,a)" /> <!-- 颜色函数 -->
<xx stroke="var(--some-color)" /> <!-- var 颜色变量 -->
<xx stroke="url(#gradientId)" /> <!-- 渐变色 -->
<xx stroke="url(#patternId)" /> <!-- 图案 -->
<xx stroke="url(#patternId) defaultColor" /> <!-- 回退语法 -->
</svg>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
这些语法和上一节的 fill
语法是一样的,所以此处不在赘述。
语法示例
相关属性
描边透明度(stroke-opacity
)
与 fill-opacity
类似,stroke
也支持单独设置颜色透明度——stroke-opacity
。
例如半透明红色描边:
html
<svg>
<xx stroke="red" stroke-opacity="0.5" />
<xx stroke="red" stroke-opacity="50%" />
</svg>
1
2
3
4
2
3
4
描边宽度(stroke-width
)
html
<svg>
<xx stroke="red" stroke-width="10">
<xx stroke="red" stroke-width="10%">
<xx stroke="red" stroke-width="3em">
<xx stroke="red" stroke-width="3rem">
</svg>
1
2
3
4
5
6
2
3
4
5
6
描边连接(stroke-linejoin
)
定义一个图形在其边角处应该使用哪种方式来连接。
html
<svg>
<path d="..." stroke-linejoin="arcs | bevel | miter | miter-clip | round" />
</svg>
1
2
3
2
3
bevel
:使用斜平面连接miter
(默认):在拐角处使用尖角连接- 当拐角特别尖锐时(也就是角度特别小、特别尖),此选项会失效、回退到
bevel
选项。 - 此时可以通过设置另一属性值(
stroke-meterlimit
)来保持尖角。stroke-meterlimit
默认为4,值越大,允许拐角越尖锐。
- 当拐角特别尖锐时(也就是角度特别小、特别尖),此选项会失效、回退到
round
:使用圆弧连接arcs
miter-clip
:这两个选项是 SVG2 引入的,目前浏览器还未支持,此时会回退到miter
。
INFO
更多说明请参考:MDN stroke-linejoin
描边帽子(stroke-linecap
)
当 <line>
<polyline>
<path>
首尾没有封闭时,此属性定义了末尾两端如何被绘制(是否戴上一个帽子 cap)。
html
<svg>
<path d="..." stroke-linecap="butt | round | square" />
</svg>
1
2
3
2
3
butt
(默认):不进行额外的绘制,也就是不戴帽子round
:在端点处绘制圆弧,会超过原来的路径,也就是戴了一个圆帽子square
:在端点处绘制正方形,会超过原来的路径,也就是戴了一个方形帽子
属性综合示例
以下的代码片段综合了以上的几个属性:
- 红色的点和线,是路径参考线
- 黑色的线才是需要绘制的路径
- 由于例子中的拐角过于尖锐,所以设置
stroke-miterlimit>=7
时才能让miter
生效
抗锯齿(shape-rendering
)
指定浏览器绘制图形时是否使用抗锯齿模式。
html
<svg xmlns="http://www.w3.org/2000/svg" width="420" height="200" viewBox="0 0 420 200" >
<circle id="myCircle" cx="100" cy="100" r="100" shape-rendering="auto | optimizeSpeed | crispEdges | geometricPrecision | inherit"/>
</svg>
1
2
3
2
3
INFO
更多说明请参考:MDN shape-rendering
绘制顺序(paint-order
)
默认情况下,SVG 先绘制 fill
,然后绘制 stroke
,因此 stroke
是绘制在 fill
之上的。 SVG2 引入了 paint-order
属性用于控制 stroke
和 fill
的绘制顺序。
html
<svg ... paint-order="normal | fill | stroke | markers" > ... </svg>
1
paint-order="normal"
(默认):即paint-order="fill stroke markers"
paint-order="stroke markers fill"
: 先stroke
、然后绘制markers
、最后fill
paint-order="stroke"
: 先stroke
、然后fill
、最后绘制markders
- 这个例子中只有
stroke
一个选项,那么就先绘制stroke
,剩余的选项会按照normal
里的顺序继续绘制。
- 这个例子中只有
矢量效果(vector-effect
)
定义绘制图形时应用何种矢量效果。
html
<svg>
<rect vector-effect="none | non-scaling-stroke | non-scaling-size | non-rotation | fixed-position" />
</svg>
1
2
3
2
3
none
:不应用矢量效果non-scaling-stroke
:当 transform="scale(2)" 时,默认情况下描边宽度也会被 scale,然而指定此选项后,描边宽度会保持不变。non-scaling-size | non-rotation | fixed-position
:这3种选项,浏览器都还没有支持。
INFO
更多选项说明请参考:MDN vector-effect
虚线(stroke-dasharray
)
前面我们用 stroke
绘制的都是实线,我们也可以通过 stroke-dasharray
属性绘制虚线。
基本语法和示例
html
<line x1="10%" y1="10%" x2="90%" y2="10%" stroke-dasharray="20 10" />
1
- 此属性的值是空格或逗号分隔的数值列表,数值可以是百分比、用户单位数量、长度。
- 第一个数字始终表示 dash 的长度,紧跟着的数字表示 gap 的长度,然后是 dash 长度,如此重复。
- 如果列表中的数值是奇数个,则重复列表使其成为偶数个,例如:
stroke-dasharray="1em 10px 1em"
=stroke-dasharray="1em 10px 1em 1em 10px 1em"
stroke-dasharray="20"
=stroke-dasharray="20 20"
- 百分比的数值,不是相对于要绘制的图形路径的长度,而是相对于坐标系统的对角线除以√2。
点线(dots)
stroke-dasharray="dash gap"
,通过设置 dash 为很小的值(小于1)、gap为相对较大的值,并且设置 stroke-linecap
为 round
或 square
,可以实现圆点线、方点线:
虚线偏移 stroke-dashoffset
html
<line ... stroke-dashoffset="10" />
1
stroke-dashoffset
:定义了第一个 dash 在 path 中的位置,例如:stroke-dashoffset="5"
:第一个 dash 开始于 path 起始点之前的 5 个用户单位stroke-dashoffset="-5"
:第一个 dash 开始于 path 起始点之后的 5 个用户单位
- 第一个红框中,默认
stroke-dashoffset="0"
,即不偏移,你可以调整stroke-dashoffset
的值来查看效果; - 第二个红框中,由于
stroke-dashoffset
是 animatable 的,所以可以利用 CSS 的 animation 对其设置动画。
笔迹动画
通过结合 stroke-dasharray
和 stroke-dashoffset
,我们可以实现笔迹动画:
- 我们使用
SVGPathElement.getTotalLength()
获取 path 的实际长度 stroke-dasharray: 456
:即 dash=456 gap=456 dash=456 gap=456 以此类推;但由于 456 比 "S" "V" "G" 任一 path 的实际长度都大,我们是看不到 gap 的,整个 path 由一个 dash 绘制而成。- 但是当我们设置
stroke-dashoffset: 456
后,dash 向前偏移 456 个单位,所以动画的一开始,我们是看不到 dash 的,看到的是 gap,然后stroke-dashoffset
逐渐变为 0,dash 也就一点点显示了出来。
渐变和图案
就像 fill
支持渐变色和图案一样,stroke
也支持。其实我们在本节开始的基本语法中也举过例子,这里我们再举一些例子:
pathLength
在学习 <path>
时,我们没有介绍 pathLength
属性的用法,这里我们来介绍一下:
<circle>
<ellipse>
<line>
<path>
<polygon>
<polyline>
<rect>
这些元素都支持pathLength
属性- 通过
SVGGeometryElement.getTotalLength()
获取的 path 长度是实际浏览器绘制的长度- SVG2 中,
getTotalLength
方法在SVGGeometryElement
里定义,然后由SVGLineElement
,SVGPathElement
等继承并实现
- SVG2 中,
- 当没有设置
pathLength
时,SVG 使用实际长度计算stroke-dasharray
stroke-dashoffset
- 然而当设置
pathLength
后,SVG 使用pathLength
来计算相关属性
- 蓝线框中,
stroke-dasharray="40"
,实际 path 长度是 320- 当没有设置
pathLength
时,由于实际长度是 320,所以可以显示 4 个 dash,4 个 gap - 当设置
pathLength=160
时,SVG 使用 160 来计算,此时可以显示 2 个 dash,2 个 gap - 如果设置
pathLength=40
,此时只能显示 1 个 dash
- 当没有设置
- 红线框中,
pathLength
是 animatable 的,不过这个属性不支持 CSS animation,但是我们可以使用 SVG<animate>
来使其动起来;我们会在后续章节中详细解释 animate。
小结
本节我们学习了 stroke
的各种用法,接下来我们学习 <marker>
元素。