# SVG 相关知识点
TIP
图形分为位图和矢量图。位图是基于颜色的描述,是由像素点组成的图像;而矢量图是基于数学矢量的描述,是由几何图元组成的图像,与分辨率无关。可缩放矢量图形,即 SVG,是 W3C XML 的分支语言之一,用于标记可缩放的矢量图形。
# SVG 基本形状和样式设置
# 矩形【rect】
rect
元素会在屏幕上绘制一个矩形 。其实只要 6 个基本属性就可以控制它在屏幕上的位置和形状
属性 | 说明 |
---|---|
x | 矩形左上角的 x 位置 |
y | 矩形左上角的 y 位置 |
width | 矩形的宽度 |
height | 矩形的高度 |
rx | 圆角的 x 方位的半径 |
ry | 圆角的 y 方位的半径 |
TIP
[注意]如果只设置 rx
或 ry
任意一个,则另一个将默认相等
如果没有设置圆角,则默认为 0
<!--可复制插入浏览器中节点展示 -->
<svg>
<rect x="10" y="10" width="30" height="30" fill="#c00" />
<rect x="60" y="10" rx="10" width="30" height="30" fill="42b983" />
</svg>
# 圆形【circle】
circle 元素会在屏幕上绘制一个圆形。它只有 3 个属性用来设置圆形
属性 | 说明 |
---|---|
r | 圆的半径 |
cx | 圆心 x 的位置 |
cy | 圆心 y 的位置 |
<svg>
<circle cx="25" cy="25" r="20" fill="#c00" />
</svg>
# 椭圆【ellipse 】
椭圆 Ellipse 是 circle 元素更通用的形式,可以分别缩放圆的 x 半径和 y 半径(通常数学家称之为长轴半径和短轴半径)
属性 | 说明 |
---|---|
rx | 椭圆的 x 半径 |
ry | 椭圆的 y 半径 |
cx | 椭圆中心的 x 位置 |
cy | 椭圆中心的 y 位置 |
<ellipse cx="25" cy="25" rx="25" ry="15" />
# 线条 【line】
TIP
线条 Line 绘制直线。它取两个点的位置作为属性,指定这条线的起点和终点位置
[注意]line 相当于只设置路径,需要设置 stroke 属性可以显示出线条
属性 | 说明 |
---|---|
x1 | 起点的 x 位置 |
y1 | 起点的 y 位置 |
x2 | 终点的 x 位置 |
y2 | 终点的 y 位置 |
<line x1="10" y1="5" x2="30" y2="50" stroke="#000" />
# 折线【polyline】
TIP
折线 Polyline 是一组连接在一起的直线。它可以有很多的点,折线的所有点位置都放在一个 points 属性中
[注意]如果不将 polyline 的 fill 设置为透明,将会呈现多边形的效果
每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。所以点列表 (0,0), (1,1) 和(2,2)可以写成这样:“0 0, 1 1, 2 2”
<polyline points="0 0, 20 30, 10 60" fill="transparent" stroke="black" />
# 多边形【polygon】
多边形 polygon 和折线很像,它们都是由连接一组点集的直线构成。不同的是,polygon 的路径在最后一个点处自动回到第一个点。
<polygon points="0 0, 20 30, 10 60" />
# 填充和描边
fill 属性和 stroke 属性。fill 属性设置对象内部的颜色,stroke 属性设置绘制对象线条的颜色
属性 | 说明 |
---|---|
fill | 设置对象内部的颜色 |
stroke | 设置绘制对象线条的颜色 |
fill-opacity | 填充色的不透明度 |
stroke-opacity | 边框色的不透明度 |
stroke-width | 描边的宽度 |
<svg>
<rect
x="10"
y="10"
width="100"
height="100"
stroke="blue"
fill="purple"
stroke-width="10"
fill-opacity="0.5"
stroke-opacity="0.8"
/>
</svg>
# SVG 文本
# 位置属性
在一个 SVG 文档中,使用<text>
元素来设置文本,<text>
元素有 x、y、dx、dy 这四个位置属性
属性 | 说明 |
---|---|
x,y | 决定了文本在视口中显示的位置 |
dx,dy | 设置文本相对于当前位置的偏移量 |
DANGER
[注意]如果不设置 y 属性,则文本将不会显示,x 属性可选。默认为 0
[注意]如果 dx 或 dy 的值是多个值(空格隔开),则从第二个值开始,表示文本内字符的间距
<svg style="border:1px dashed #eee">
<text x="30" y="30">Hello World!</text>
<text x="30" y="50" dx="10" dy="20">Hello World!</text>
</svg>
<svg style="border:1px dashed #eee">
<text x="30" y="30" dx="10 10 20 10">Hello World!</text>
</svg>
# 对齐属性
# 水平对齐
text-anchor
用来设置水平对齐,取值包括:start、middle、end 或 inherit
<svg style="border:1px dashed #eee">
<circle cx="100" cy="50" r="3" fill="red"></circle>
<circle cx="100" cy="80" r="3" fill="red"></circle>
<circle cx="100" cy="110" r="3" fill="red"></circle>
<text x="100" y="50" text-anchor="start">Hello World!</text>
<text x="100" y="80" text-anchor="middle">Hello World!</text>
<text x="100" y="110" text-anchor="end">Hello World!</text>
</svg>
# 垂直对齐
dominant-baseline
可以设置垂直对齐,包括以下属性
- auto
- use-script
- reset-size
- ideographic
- alphabetic
- hanging
- mathematical
- central
- middle
- text-after-edge
- text-before-edge
- inherit
# 样式属性
属性 fill 可以给文本填充颜色,属性 stroke 可以给文本描边,也可以引用渐变或图案
字体相关属性,下列每个属性可以被设置为一个 SVG 属性或者成为一个 CSS 声明:font-family
、font-style
、font-weight
、font-variant
、font-stretch
、font-size
、font-size-adjust
、kerning
、letter-spacing
、word-spacing
和text-decoration
<svg height="30" style="border:1px dashed #eee">
<text
y="20"
font-size="20px"
font-weight="bold"
stroke="red"
fill="transparent"
>
Hello World!
</text>
</svg>
# tspan
tspan 元素用来标记大块文本的子部分,它必须是一个 text 元素或别的 tspan 元素的子元素。一个典型的用法是把句子中的一个词变成粗体
<text x="10" y="50"> <tspan font-weight="bold">hello </tspan>World!</text>
tspan 新自定义属性
属性 | 说明 |
---|---|
x | 设置一个新绝对 x 坐标。它覆盖了默认的当前的文本位置。这个属性可以包含一个数列,它们将一个一个地应用到 tspan 元素内的每一个字符上 |
dx | 从当前位置,用一个水平偏移开始绘制文本。这里,可以提供一个值数列,可以应用到连续的字体,因此每次累积一个偏移类似地,还有 y 和 dy |
rotate | 把所有的字符旋转一个角度。如果是一个数列,则使每个字符旋转分别旋转到那个值,剩下的字符根据最后一个值旋转 |
textLength | 给出字符串的计算长度。它意味着如果它自己的度量文字和长度不满足这个提供的值,则允许渲染引擎精细调整字型的位置 |
<svg height="30" style="border:1px dashed #eee">
<text x="10" y="20">
Hello
<tspan x="100" dx="0 10 10 10" rotate="30" font-weight="bold">World!</tspan>
</text>
</svg>
# textPath
该元素利用路径文本 textPath 的 xlink:href 属性取得一个任意路径,把字符对齐到路径,于是字体会环绕路径、顺着路径走
DANGER
该元素利用路径文本 textPath 的 xlink:href 属性取得一个任意路径,把字符对齐到路径,于是字体会环绕路径、顺着路径走
<svg width="300" height="80">
<path
id="my_path"
d="M 20,20 C 50 50, 160 50, 160 20"
stroke="#333"
fill="none"
/>
<text>
<textPath xlink:href="#my_path">Hello World!</textPath>
</text>
</svg>
DANGER
- 使用 textPath 后,text 元素的 x 和 y 属性的含义有所改变
- x 路径位置
- y 无效
- textPath 只有一个 startOffset 属性,用来确定排列起始位置
# SVG 路径
# path 字符串
路径(path)是一个非常强大的绘图工具,可以用 path 元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2 次曲线等曲线
SVG 路径最常用的属性是 d 属性,即 path 字符串,用来定义 path 元素的路径形状
属性 d 的值是一个“命令+参数”的序列,每一个命令都用一个关键字母来表示。
Path 命令有如下规律
- 1、区分大小写:每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对位置。另一种是用小写字母,表示采用相对位置
- 2、最后的参数表示最终要到达的位置
- 3、上一个命令结束的位置就是下一个命令开始的位置
- 4、命令可以重复参数表示重复执行同一条命令
- 5、因为属性 d 采用的是用户坐标系统,所以不需标明单位
# 直线路径
5 个画直线的命令
- M (moveto):需要两个参数(x 轴和 y 轴坐标,移动到的点的 x 轴和 y 轴的坐标
- L (lineto):需要两个参数(x 轴和 y 轴坐标),它会在当前位置和最新的位置(L 前面画笔所在的点)之间画一条线段。
- H (horizontal lineto):一个参数,标明在 x 轴移动到的位置,绘制水平线
- V (vertical lineto):一个参数,标明在 y 轴移动到的位置,绘制垂直线
- Z (closepath):从当前点画一条直线到路径的起点
TIP
“Move to”命令,M 需要两个参数,分别是需要移动到的点的 x 轴和 y 轴的坐标。假设,画笔当前位于一个点,在使用 M 命令移动画笔后,只会移动画笔,但不会在两点之间画线。因为 M 命令仅仅是移动画笔,但不画线。所以 M 命令经常出现在路径的开始处,用来指明从何处开始画
<svg width="100" height="100" style="border:1px dashed #eee">
<!-- L x y 或 l dx dy -->
<text x="20" y="50">M L 命令</text>
/
<path d="M 10 50 L 90 50" fill="none" stroke="#333"></path>
</svg>
<svg width="100" height="100" style="border:1px dashed #eee">
<!-- H x 或 h dx-->
<text x="20" y="50">M H 命令</text>
<path d="M 10 50 H 90" fill="none" stroke="#333"></path>
</svg>
<svg width="100" height="100" style="border:1px dashed #eee">
<!-- V y 或 v dy -->
<text x="0" y="20">
<textPath xlink:href="#_mv">M V 命令</textPath>
</text>
<path id="_mv" d="M 50 10 V 90" fill="none" stroke="#333"></path>
</svg>
<!-- 闭合路径 Z / z-->
<svg width="100" height="100" style="border:1px dashed #eee">
<path d="M 10 10 H 90 V 90 Z" fill="none" stroke="#333"></path>
</svg>
# 弧形路径
基本上,弧形可以视为圆形或椭圆的一部分。假设,已知椭圆形的长轴半径和短轴半径,另外已知两个点(它们的距离在圆的半径范围内),这时有两个路径可以连接这两个点。每种情况都可以生成出四种弧形。所以,为了保证创建的弧形唯一,A 命令需要用到比较多的参数
A 命令用于画弧形
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
参数 | 参数说明 |
---|---|
rx ry | 椭圆的长半轴 椭圆的短半轴 |
x-axis-rotation | 该段弧 所在椭圆的 x 轴与水平方向的夹角 |
large-arc-flag | 决定弧线是大于还是小于 180 度,0 表示小角度弧,1 表示大角度弧。 |
sweep-flag | 表示弧线的方向,0 表示从起点到终点沿逆时针画弧,1 表示从起点到终点沿顺时针画弧。 |
x | 绘制结束点 x 坐标。 |
y | 绘制点 y 坐标。 |
<!-- MDN -->
<svg
width="325"
height="325"
xmlns="http://www.w3.org/2000/svg"
style="border: 1px dashed #eee"
>
<path
d="M 80 80
A 45 45, 0, 0, 0, 125 125
L 125 80 Z"
fill="green"
/>
<path
d="M 230 80
A 45 45, 0, 1, 0, 275 125
L 275 80 Z"
fill="red"
/>
<path
d="M 80 230
A 45 45, 0, 0, 1, 125 275
L 125 230 Z"
fill="purple"
/>
<path
d="M 230 230
A 45 45, 0, 1, 1, 275 275
L 275 230 Z"
fill="blue"
/>
</svg>
# 贝塞尔曲线
# SVG 辅助标签
# 超链接
在 SVG 中,可以使用超链接<a>
。超链接可以添加到任意的图形上
超链接有如下 3 个常用属性
xlink:href 指定链接地址
xlink:title 指定链接标题
target 指定打开方式
<svg height="100" style="border:1px dashed #eee">
<a xlink:href="https://juncaihe.com" target="_blank">
<circle r="20" cx="100" cy="50" stroke="#333" fill="transparent"></circle>
</a>
<a xlink:href="https://juncaihe.com" target="_blank">
<rect
x="150"
y="25"
width="80"
height="50"
stroke="#333"
fill="transparent"
></rect>
</a>
</svg>
# 辅助标签
四个常用的辅助标签:<g>
、<use>
、<symbol>
、<defs>
# g
<g>
是一个分组(容器)标签,用来组合元素。可以设置一组元素的属性
DANGER
由于<g>
是一个通用的分组标签,可以包含任何形状,因此其只能设置所有形状都有的属性,
包括 stroke、fill 等。由于 cx、cy 是圆特有的属性,所以无法在<g>
上设置
<!-- <svg height="200" style="border:1px dashed #eee">
<circle r="20" cx="60" cy="60" fill="#42b983" stroke="#333" stroke-width="2"></circle>
<circle r="20" cx="150" cy="90" fill="#42b983" stroke="#333" stroke-width="2"></circle>
<circle r="20" cx="190" cy="120" fill="#42b983" stroke="#333" stroke-width="2"></circle>
<circle r="20" cx="100" cy="100" fill="#42b983" stroke="#333" stroke-width="2"></circle>
</svg> -->
<!-- 只需要改一处属性 组内元素对应属性也全改变-->
<svg height="200" style="border:1px dashed #eee">
<g fill="#42b983" stroke="#333" stroke-width="2">
<circle r="20" cx="60" cy="60"></circle>
<circle r="20" cx="150" cy="90"></circle>
<circle r="20" cx="190" cy="120"></circle>
<circle r="20" cx="100" cy="100"></circle>
<rect x="60" y="150" width="100" height="30"></rect>
</g>
</svg>
# defs
TIP
SVG 允许定义以后需要重复使用的图形元素。 建议把所有需要再次使用的引用元素定义在 defs 元素里面。这样做可以增加 SVG 内容的易读性和可访问性。 在 defs 元素中定义的图形元素不会直接呈现
<svg width="100px" height="100px">
<defs>
<linearGradient id="Gradient01">
<stop offset="20%" stop-color="#39F" />
<stop offset="90%" stop-color="#F3F" />
</linearGradient>
</defs>
<rect x="10" y="10" width="60" height="10" fill="url(#Gradient01)" />
<circle r="20" cx="40" cy="50" fill="url(#Gradient01)"></circle>
</svg>
# use
TIP
use元素
在 SVG 文档内取得目标节点,并在别的地方复制它们。它的效果等同于这些节点被深克隆到一个不可见的 DOM 中,然后将其粘贴到 use 元素的位置
因为克隆的节点是不可见的,所以当使用 CSS 样式化一个 use 元素以及它的隐藏的后代元素的时候,隐藏的、克隆的 DOM 不能保证继承 CSS 属性,除非明文设置使用 CSS 继承。
出于安全原因,一些浏览器可能在 use 元素上应用同源策略,还有可能拒绝载入 xlink:href 属性内的跨源 URI。
<svg
height="100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<style>
.classA {
fill: red;
}
</style>
<defs>
<g id="Port">
<circle style="fill:inherit" r="10" />
</g>
</defs>
<text y="15">black</text>
<use x="50" y="10" xlink:href="#Port" />
<text y="35">red</text>
<use x="50" y="30" xlink:href="#Port" class="classA" />
<text y="55">blue</text>
<use x="50" y="50" xlink:href="#Port" style="fill:blue" />
</svg>
# symbol
TIP
symbol
元素用来定义一个图形模板对象,它可以用一个<use>
元素实例化。symbol
元素对图形的作用是在同一文档中多次使用,添加结构和语义,从而提升了可访问性
一个symbol
元素本身是不呈现的。只有symbol
元素的实例(亦即,一个引用了 symbol 的 <use>
元素)才能呈现
一个<symbol>
元素可以有 preserveAspectRatio 和 viewBox 属性。而<g>
元素不能拥有这些属性。因此相比于在<defs>
元素中使用<g>
的方式来复用图形,使用<symbol>
元素也许是一个更好的选择
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<symbol id="sym01" viewBox="0 0 150 110">
<circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red" />
<circle
cx="90"
cy="60"
r="40"
stroke-width="8"
stroke="green"
fill="white"
/>
</symbol>
<use xlink:href="#sym01" x="0" y="0" width="100" height="50" />
<use xlink:href="#sym01" x="0" y="50" width="75" height="38" />
<use xlink:href="#sym01" x="0" y="100" width="50" height="25" />
</svg>
# SVG视野
# 视窗✨
SVG的属性width、height
来控制视窗的大小,也称为SVG容器
# 世界🔮
SVG里面的代码,就是对SVG世界的定义 (显示内容)
# 视野🎦
世界是无穷大的,视野是观察世界的一个矩形区域。视窗内得可视区域 如下图所示
TIP
世界不可变,而视野是可以改变的。在SVG中,提供了viewBox和preserveAspectRatio属性来控制视野
# viewbox
- viewBox属性允许指定一个给定的一组图形伸展以适应特定的容器元素
- viewBox属性的值是一个包含4个参数的列表
min-x
,min-y
,width
andheight
, 以空格或者逗号分隔开, 在用户空间中指定一个矩形区域映射到给定的元素
SVG 可视区域效果
<!-- svg画布大小 === 可视范围 -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" style="background-color: green;">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</svg>
<!-- svg画布大小 < 可视范围 -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 400 400" style="background-color: green;">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</svg>
<!-- svg画布大小 > 可视范围 -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100" style="background-color: green;">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</svg>
TIP
svg画布大小 > 可视范围
如果不看viewBox
,一定会觉得诧异。SVG尺寸明明有200*200
像素,而小小的<rect>
大小只有其50*50
,但是显示出来的图形占据了大量的区域
SVG里面的图形等元素的尺寸是依据viewBox的width、height设置来布局的。最终,再把viewBox的尺寸放大到视窗的尺寸大小来显示
# 结论
世界是无穷大的。viewBox的尺寸设置的越大,即视野越大,则可显示的世界的区域就越大。由于视窗大小是固定的,因此,SVG内部元素尺寸看上去就越小。反之亦然
# preserveAspectRatio
上面的例子,SVG的宽高比正好和viewBox的宽高比是一样的,都是4:3。显然,实际应用viewBox不可能一直跟viewport相同比例。此时,就需要preserveAspectRatio
出马了,此属性也是应用在<svg>
元素上,且作用的对象都是viewBox
preserveAspectRatio
属性的值为空格分隔的两个值组合而成。第一个值表示,viewBox如何与SVG viewport对齐;第二个值表示,如何维持高宽比(如果有)
其中,第1个值又是由两部分组成的。前半部分表示x方向对齐,后半部分表示y方向对齐
值 含义
xMin viewport和viewBox左边对齐
xMid viewport和viewBox x轴中心对齐
xMax viewport和viewBox右边对齐
YMin viewport和viewBox上边缘对齐。注意Y是大写。
YMid viewport和viewBox y轴中心点对齐。注意Y是大写。
YMax viewport和viewBox下边缘对齐。注意Y是大写。
然后,把x和y进行组合,比如xMinYMin、xMidYMin
preserveAspectRatio属性第二部分的值支持下面3个
值 含义
meet 保持纵横比缩放viewBox适应viewport
slice 保持纵横比同时比例小的方向放大填满viewport
none 扭曲纵横比以充分适应viewport
WARNING
- [注意]preserveAspectRatio属性第二部分的值设置为none时,第一部分的值必须为空,否则报错
- 如果不设置preserveAspectRatio属性,默认是xMidYMid、meet属性
可视区域效果 + preserveAspectRatio + viewBox
preserveAspectRatio - align: meetOrSlice:# SVG 坐标系统及图形变换
# SVG 坐标系统及图形变换
# SVG 图案
# SVG 裁切和蒙版
# SVG 动画
# SVG 基本操作 API
← Dom 相关基础知识点 console →