svg

什么是 svg

svg 是矢量图的一种格式。用 xml 来描述图形。

  • 位图:放大会失真图像边缘有锯齿;是由像素点组成; Canvas 就是位图效果。
  • 矢量图:放大不会失真;使用 XML 描述图形。

和 html 的关系

使用时可以将其理解为 html 的新标签

1
<svg></svg>

在不给 <svg> 设置宽高时,它的默认宽度是 300px ,默认高度是 150px 。和 canvas 一致

HTML 的元素大多数默认都是矩形,SVG 在形状上更加丰富。

基础图形

矩形 rect

矩形使用 <rect> 标签,默认填充色是黑色,当只设置宽高时,渲染出来的矩形就是黑色的矩形。

稍后还会说明如何设置样式(比如边框、填充色等),这里只列出矩形基础属性:

  • x: 左上角x轴坐标
  • y: 左上角y轴坐标
  • width: 宽度
  • height: 高度
  • rx: 圆角,x轴的半径
  • ry: 圆角,y轴的半径

圆形 circle

圆形使用 <circle> 标签,基础属性有:

  • cx: 圆心在x轴的坐标
  • cy: 圆心在y轴的坐标
  • r: 半径

椭圆 ellipse

椭圆使用 <ellipse> 标签,基础属性有:

  • cx: 圆心在x轴的坐标
  • cy: 圆心在y轴的坐标
  • rx: x轴的半径
  • ry: y轴的半径

<ellipse><circle> 差不多,只是将半径拆成x轴和y轴的。

直线 line

直线使用 <line> 标签,基础属性有:

  • x1: 起始点x坐标
  • y1: 起始点y坐标
  • x2: 结束点x坐标
  • y2: 结束点y坐标
  • stroke: 描边颜色

折线 polyline

使用 <polyline> 可以绘制折线,基础属性有:

  • points: 一串点集,点集是两两一组表示一个坐标。
  • stroke: 描边颜色
  • fill: 填充颜色

多边形 polygon

多边形使用 <polygon> 标签,基础属性和 <polyline> 差不多:

  • points: 点集
  • stroke: 描边颜色
  • fill: 填充颜色

<polygon> 会自动闭合(自动将起始点和结束点链接起来)。

直线路径 path

其实在 SVG 里,所有基本图形都是 <path> 的简写。所有描述轮廓的数据都放在 d 属性里,ddata 的简写。

d 属性又包括以下主要的关键字(注意大小写!):

  • M: 起始点坐标,moveto 的意思。每个路径都必须以 M 开始。M 传入 xy 坐标,用逗号或者空格隔开。
  • L: 轮廓坐标,lineto 的意思。L 是跟在 M 后面的。它也是可以传入一个或多个坐标。大写的 L 是一个绝对位置
  • l: 这是小写 L,和 L 的作用差不多,但 l 是一个相对位置
  • H: 和上一个点的Y坐标相等,是 horizontal lineto 的意思。它是一个绝对位置
  • h: 和 H 差不多,但 h 使用的是相对定位
  • V: 和上一个点的X坐标相等,是vertical lineto 的意思。它是一个绝对位置
  • v: 这是一个小写的 v ,和大写 V 的差不多,但小写 v 是一个相对定位。
  • Z: 关闭当前路径,closepath 的意思。它会绘制一条直线回到当前子路径的起点。

概念说了一堆,还是用写 demo 的方式来展示会更加直观。

曲线 - 椭圆弧路径 path

如果只用两个点,可以产生无数条曲线。所以需要添加更多的参数来确定如何绘制一条曲线。而在种种方法中, 椭圆弧曲线 是最简单的。

SVG 中可以使用 path 配合 A属性 绘制椭圆弧。

1
A(rx, ry, xr, laf, sf, x, y)
  • rx: 椭圆X轴半径
  • ry: 椭圆Y轴半径
  • xr: 椭圆旋转角度
  • laf: 是否选择弧长较长的那一段。0: 短边(小于180度); 1: 长边(大于等于180度)
  • sf: 是否顺时针绘制。0: 逆时针; 1: 顺时针
  • x: 终点X轴坐标
  • y: 终点Y轴坐标

上面的公式中并没有开始点,开始点是由 M 决定的

也就是说,M和x, y确定2个点,再由rx,ry,xr确定两个椭圆。两个椭圆被切割为4条曲线段,通过 las 和 sf 确定要的是哪条。

绘制弧线是比较抽象的,可以使用 Illustrator 绘制,然后生成 SVG 来使用。

常用样式

填充 fill

填充图案颜色,fill 默认是 #000000 黑色。

也可以使用 none 或者 transparent 将填充色设置成透明。

填充色的不透明度 fill-opacity

和 css 的 opacity 一样

描边颜色 stroke

可以通过 stroke 属性设置描边的颜色。如果不设置 stroke ,图形默认是没有描边颜色的。

描边颜色的不透明度 stroke-opacity

fill-opacity 差不多,只不过 stroke-opacity 是设置描边的不透明度

描边宽度 stroke-width

如果需要调整描边的宽度,可以使用 stroke-width,它接收一个数值

虚线描边 stroke-dasharray

stroke-dasharray 接收一串数字,这串数字可以用来代表 线的长度和空隙的长度,数字之间用逗号或者空格分隔。

建议传入偶数个数字。但如果你传入了奇数个数字,SVG 会将这串数字重复一遍,使它的数量变成 偶数个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<svg width="400" height="400" style="border: 1px solid red;">
<line
x1="30"
y1="30"
x2="300"
y2="30"
stroke="blue"
/>

<!-- 线长20 空隙长10 -->
<line
x1="30"
y1="70"
x2="300"
y2="70"
stroke="blue"
stroke-dasharray="20 10"
/>

<!-- 线长20 空隙长10 线长30 空隙长20 线长10 空隙长30 -->
<line
x1="30"
y1="110"
x2="300"
y2="110"
stroke="blue"
stroke-dasharray="20 10 30"
/>
</svg>

虚线偏移量 stroke-dashoffset

虚线还可以通过 stroke-dashoffset 属性设置偏移量,它接收一个数值类型的值。

1
stroke-dashoffset="10"

线帽 stroke-linecap

线帽就是线的起始点和结束点的位置,用 stroke-linecap 属性可以设置线帽样式。

线帽有3个值:

  • butt: 平头(默认值)
  • round: 圆头
  • square: 方头

拐角 stroke-linejoin

拐角就是折线的交接点,可以使用 stroke-linejoin 设置,它接收以下属性:

  • miter: 尖角(默认)
  • round: 圆角
  • bevel: 平角

消除锯齿 shape-rendering

如果 SVG 在浏览器显示出来的图像有点模糊,那可能是开启了 反锯齿 功能,可以通过 CSS 属性关闭该功能。

1
2
3
4
// 开启反锯齿
shape-rendering: geometricPrecision
// 关闭反锯齿
shape-rendering: crispEdges

将该属性设置到对应的 svg 元素上,就会关闭反锯齿功能,突显看起来就会清晰很对,但在某些情况关闭了该功能会让图像看起来有点毛躁的感觉。

文本元素

SVG 可以使用 <text> 标签渲染文本。

基础版

Canvas 一样,SVG 的文本对齐方式是以第一个字基线的左下角为基准。

1
2
3
<svg width="400" height="400" style="border: 1px solid red;">
<text>雷猴啊</text>
</svg>

所以如果不设置 text 的位置,那么 text 会跑到左上角,第一个字基线的左下角和 svg 顶部对齐。

假设字体为 16px 大小,可以设置 text 向下移16px,这样就能完整看到了

1
2
3
<svg width="400" height="400" style="border: 1px solid red;">
<text y="16">雷猴啊</text>
</svg>

设置字号 font-size

粗体 font-weight

使用 font-weight 可以将文本设置成粗体。

  • normal: 默认(非粗体)
  • bold: 粗体

装饰线 text-decoration

CSS 一样,可以使用 text-decoration 设置装饰线

  • none:默认
  • underline: 下划线
  • overline: 上划线
  • line-through: 删除线

水平对齐方式 text-anchor

可以通过 text-anchor 属性设置文本水平对齐方式。

如果文本是从左向右书写,那这几个参数的意思就是:

  • start: 左对齐
  • middle: 居中对齐
  • end: 右对齐

text 会有坐标 x y,左对齐指文本最左侧和坐标重叠,右对齐指文本最右侧和坐标重叠。

从上到下依次是,左对齐、居中对齐、右对齐

多行文本

多行文可以使用 <tspan> 标签辅助实现

1
2
3
4
5
6
7
8
<svg width="400" height="400" style="border: 1px solid red;">
<text fill="blue">
<tspan x="10" y="30" fill="red">111</tspan>
<tspan x="10" y="60">222</tspan>
<tspan x="10" y="90">333</tspan>
<tspan x="10" y="120">444</tspan>
</text>
</svg>

<tspan> 要放在 <text> 里,而且会继承 <text> 设置的样式。

垂直对齐方式 dominant-baseline

可以通过 dominant-baseline 属性设置文本垂直对齐方式

  • auto: 默认的对齐方式,保持与父元素相同的配置。
  • text-after-edge: 在基线上方
  • middle: 居中基线
  • text-before-edge: 在基线下方

纵向文字 writing-mode

writing-mode 设置成 tb 就可以让文字纵向排列。

超链接

1
2
3
4
5
<svg width="400" height="400" style="border: 1px solid red;">
<a xlink:href="https://juejin.cn/post/7116784455561248775" xlink:title="canvas" target="_blank">
<text x="20" y="20">也学学Canvas吧</text>
</a>
</svg>

超链接也是 a 标签

xlink:href 链接

xlink:title 鼠标放到链接上的提示信息

target="_blank" 需要在新窗口打开链接

标签里除了可以包裹文本外,还可以包裹各种图形和图片等元素。

图片 image

1
2
3
<svg width="400" height="400" style="border: 1px solid red;">
<image xlink:href="./img.jpg"></image>
</svg>

结构元素

分组 g

它能把多个元素放在一组里,对标记实施的样式和渲染会作用到这个分组内的所有元素上。组内的所有元素都会继承标记上的所有属性。

1
2
3
4
5
6
7
8
9
10
<svg viewBox="-10 -10 220 220">
<g fill="none" stroke-width="9" transform="translate(100,100)">
<path d="M 0,-100 A 100,100 0 0,1 86.6,-50" stroke="url(#cl1)"/>
<path d="M 86.6,-50 A 100,100 0 0,1 86.6,50" stroke="url(#cl2)"/>
<path d="M 86.6,50 A 100,100 0 0,1 0,100" stroke="url(#cl3)"/>
<path d="M 0,100 A 100,100 0 0,1 -86.6,50" stroke="url(#cl4)"/>
<path d="M -86.6,50 A 100,100 0 0,1 -86.6,-50" stroke="url(#cl5)"/>
<path d="M -86.6,-50 A 100,100 0 0,1 0,-100" stroke="url(#cl6)"/>
</g>
</svg>

defs 定义可重用部分

defs 用于嵌入可在 SVG 映像内重用的定义。

使用 defs 元素, 可以将 SVG 形状组合在一起, 并将其作为单个形状重复使用。(mixin?)

通过 use 元素引用 defs 元素中定义的形状时, 将显示该形状。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<body>

<svg>
<defs>
<g id="shape">
<rect x="40" y="40" width="40" height="40" />
<circle cx="40" cy="40" r="40" />
</g>
</defs>

<use xlink:href="#shape" x="40" y="40" />
<use xlink:href="#shape" x="160" y="40" />

</svg>

</body>
</html>

重要属性

viewBox 视区盒子

1
viewBox="x, y, width, height"  // x:左上角横坐标,y:左上角纵坐标,width:宽度,height:高度

svg 的宽高也许很大,但设定了 viewBox,就只显示 viewBox 这一块区域。

下图为 不设置 viewBox 到设置 viewBox="0,0,40,30"

渐变

渐变色(gradient)是指从一种颜色平滑的过渡到另外一种颜色。而且,我们可以将多种渐变色应用到同一个网页元素上。

在SVG里,有两种主要的渐变色类型:

  • 线性渐变色 Linear
  • 辐射式(放射式)渐变色 Radial

SVG线性渐变色 – linearGradient

linearGradient 标记就是用来定义渐变色的。

linearGradient 标记必须放在 defs 标记内。defs 标记就是“definitions”单词的简写,用来容纳其它各种 SVG 标记。

线性渐变色可以定义成水平渐变色,垂直渐变色和斜向渐变色:

  • y1y2相等,而x1x2不等时,就形成了水平渐变色
  • y1y2不等,而x1x2相等时,就形成了垂直渐变色
  • y1y2不等,而x1x2也不等时,就形成了斜向渐变色

示例:

1
2
3
4
5
6
7
8
9
<svg height="150" width="400">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>
  • linearGradient 标记的id属性定义了这个渐变色的唯一标志
  • linearGradient 标记的x1, x2, y1,y2四个属性定义了渐变色的起始位置和终止位置
  • 渐变色的颜色组成可以是2个或2个以上的颜色。每种颜色都使用一个 stop 标记定义。offset属性用来定义渐变色的开始和结束位置。
  • fill属性定义了需要引用的渐变色的ID

在线 svg 绘制网站

https://www.jq22.com/code2254

参考

https://juejin.cn/post/7118985770408345630 本篇内容主要来源于这篇文章

http://know.webhek.com/svg/svg-home.html

https://www.srcmini.com/37390.html


svg
http://example.com/2022/09/29/svg/
Author
John Doe
Posted on
September 29, 2022
Licensed under