【笔记】SVG学习笔记

前言

可缩放矢量图形(英語:Scalable Vector Graphics,縮寫:SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。(维基百科

定义SVG

通过SVG文件定义SVG

1.x

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
width="300px"
height="150px"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
...
</svg>

2.x

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg
width="300px"
height="150px"
xmlns="http://www.w3.org/2000/svg"
>
...
</svg>

通过HTML的svg标签定义SVG

1.x

1
2
3
4
5
6
7
8
9
<svg
width="300px"
height="150px"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
...
</svg>

2.x

1
2
3
4
5
6
7
<svg
width="300px"
height="150px"
xmlns="http://www.w3.org/2000/svg"
>
...
</svg>

简写

  • 默认宽为300px,高为150px
1
2
3
<svg>
...
</svg>

通过HTML的img标签引入SVG

1
<img src="<file>.svg">

通过CSS的url()引入SVG

1
2
3
4
div {
background-image: url(<file>.svg);
background-repeat: no-repeat;
}

通过JS的DOM操作创建SVG

1
2
3
4
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttributeNS(null, "width", "300px");
svg.setAttributeNS(null, "height", "150px");
document.body.appendChild(svg);

视口坐标系和用户坐标系

  • 通过widthheight属性定义的宽高,即为视口坐标系;通过viewBox属性定义的宽高,即为用户坐标系

    • 如果没有定义viewBox属性,则默认与视口坐标系一致
  • 如果视口坐标系与用户坐标系不一致

    • 如果视口坐标系宽高比与用户坐标系宽高比一致,则用户坐标系最终会等比例缩放到视口坐标系大小
    • 如果视口坐标系宽高比与用户坐标系宽高比不一致,则可以使用preserveAspectRatio属性控制用户坐标系的缩放方式
1
2
3
<svg width="300px" height="150px" viewBox="0 0 300 150">
...
</svg>

绘制图形

  • 绘图时都是基于用户坐标系进行绘制

fill="":填充颜色

black:缺省值,黑色
transparent:透明
currentColor:继承自身或父级字体颜色

fill-opacity="":填充透明度
stroke="":线条颜色
stroke-width="":线条宽度
stroke-opacity="":线条透明度
stroke-linecap="":线条端点样式

butt:缺省值,截断
round:圆形
square:方形

stroke-linejoin="":线条连接样式

miter:缺省值,尖角
round:圆角
bevel:平角

stroke-dasharray="":线条虚线样式,索引为奇数的数字表示实线长度,索引为偶数的数字表示空隙长度,多个数字用逗号分隔,空格会被忽略

1:填充1、空白1,如此往复
1,2:填充1、空白2,如此往复

stroke-dashoffset="":线条虚线偏移量

绘制矩形

rx="":定义x轴方向的圆角半径
ry="":定义y轴方向的圆角半径

1
2
3
<svg>
<rect x="0" y="0" width="10" height="10"></rect>
</svg>

绘制圆形

cx="":圆心的x坐标
cy="":圆心的y坐标
r="":圆的半径
fill="":填充颜色

1
2
3
<svg>
<circle cx="10" cy="10" r="10"></circle>
</svg>

绘制椭圆

cx="":圆心的x坐标
cy="":圆心的y坐标
rx="":椭圆的x轴半径
ry="":椭圆的y轴半径

1
2
3
<svg>
<ellipse cx="10" cy="10" rx="10" ry="10"></ellipse>
</svg>

绘制直线

x1="":起始点的x坐标
y1="":起始点的y坐标
x2="":结束点的x坐标
y2="":结束点的y坐标

1
2
3
<svg>
<line x1="0" y1="0" x2="10" y2="10"></line>
</svg>

绘制折线

  • 折线默认不会自动闭合

points="":折线点坐标

1
2
3
<svg>
<polyline points="0,0 10,10 20,20"></polyline>
</svg>
1
2
3
<svg>
<polyline points="0 0 10 10 20 20"></polyline>
</svg>

绘制多边形

  • 多边形默认自动闭合

points="":折线点坐标

1
2
3
<svg>
<polygon points="0,0 10,10 20,20"></polygon>
</svg>

绘制路径

  • 路径默认不会自动闭合

d="":路径数据

M :移动到指定点
L :缺省值,绘制直线
Z:闭合路径

1
2
3
<svg>
<path d="M 0,0 L 10,10 L 20,20 Z"></path>
</svg>

绘制文本

text-anchor="":定义文本对齐方式

start:缺省值,从文本的起始位置开始绘制
middle:从文本的中间位置开始绘制
end:从文本的末尾位置开始绘制

dominant-baseline="":定义文本基线

auto:缺省值,自动
alphabetic:文本内容英文基线与坐标位置对齐
ideographic:文本内容英文表意基线与坐标位置对齐
hanging:文本内容悬挂基线与坐标位置对齐
mathmathematical:文本内容数学基线与坐标位置对齐

1
2
3
<svg>
<text x="0" y="0">文本内容</text>
</svg>

绘制嵌套文本

  • <tspan></tspan>只能作为<text></text><tspan></tspan>的子元素
1
2
3
4
5
<svg>
<text>
<tspan x="0" y="0">文本内容</tspan>
</text>
</svg>
1
2
3
4
5
6
7
<svg>
<text>
<tspan>
<tspan x="0" y="0">文本内容</tspan>
</tspan>
</text>
</svg>

绘制图片

1.x

1
2
3
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="10" height="10" xlink:href="<file>.png"></image>
</svg>

2.x

1
2
3
<svg>
<image x="0" y="0" width="10" height="10" href="<file>.png"></image>
</svg>

组合

  • 编组后为一组元素统一设置样式
1
2
3
4
5
<svg>
<g>
...
</g>
</svg>

复用

  • <defs></defs>定义的容器和<symbol></symbol>定义的图形模板是全局的,可以跨<svg></svg>通过<use></use>复用

通过<defs></defs>定义容器

  • <defs></defs>不支持SVG容器的通用属性

定义图形

1
2
3
4
5
<svg>
<defs>
<rect id="id" x="0" y="0" width="10" height="10"></rect>
</defs>
</svg>

定义组合

1
2
3
4
5
6
7
<svg>
<defs>
<g id="id">
...
</g>
</defs>
</svg>

通过<symbol></symbol>定义图形模板

  • <symbol></symbol>支持SVG容器的通用属性,如:viewBox
1
2
3
4
5
<svg>
<symbol id="id">
<rect x="0" y="0" width="10" height="10"></rect>
</symbol>
</svg>

通过<use></use>复用

width="":如果定义的图形有viewBox属性,则可以指定复用后的图形宽
height="":如果定义的图形有viewBox属性,则可以指定复用后的图形高

1.x

1
2
3
<svg>
<use x="0" y="0" xlink:href="#id"></use>
</svg>

2.x

1
2
3
<svg>
<use x="0" y="0" href="#id"></use>
</svg>

渐变

通过<defs></defs>定义渐变

线性渐变

x1:渐变起始点x轴坐标,缺省值为0%
y1:渐变起始点y轴坐标,缺省值为50% x2:渐变结束点x轴坐标,缺省值为100% y2:渐变结束点y轴坐标,缺省值为50%`

定义形变="":形变,传递形变函数

1
2
3
4
5
6
7
8
9
<svg>
<defs>
<linerGradient id="id" x1="0%" y1="50%" x2="100%" y2="50%" gradientTransform="rotate(180)">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linerGradient>
</defs>
</svg>

使用渐变

1
2
3
<svg>
<rect x="0" y="0" width="10" height="10" fill="url(#id)"></rect>
</svg>

滤镜

x:开始位置x轴坐标,缺省值是-10%
y:开始位置y轴坐标,缺省值是-10%
width:滤镜范围宽度,缺省值为120%
height:滤镜范围高度,缺省值为120%

1
2
3
4
5
<svg>
<defs>
<filter id="id" x="-10%" y="-10%" width="120%" height="120%"></filter>
</defs>
</svg>

高斯模糊

stdDeviation:模糊偏差值,最小值为0表示没有模糊

1
2
3
4
5
6
7
<svg>
<defs>
<filter id="id">
<feGaussianBlur stdDeviation="0"></feGaussianBlur>
</filter>
</defs>
</svg>

形变

transform="":定义形变,传递形变函数,传递的值不需要单位,可以传递多个形变函数,多个形变函数用空格隔开

translate(<x>, <y>)translate(<x>):平移,坐标轴原点会被平移
rotate(<z>)rotate(<z>, <cx>, <cy>):旋转,坐标轴会被旋转

<cx><cy>:旋转圆心坐标

scale(<x>, <y>)scale(<x_y>):缩放,坐标轴会被缩放

<x_y>:同时指定x轴和y轴缩放倍率

skew(<x>, <y>):倾斜
matrix(<a>, <b>, <c>, <d>):2*3形变矩阵

1
2
3
<svg>
<rect transform=""></rect>
</svg>

通过SMIL实现动画

同步多媒体集成语言(Synchronized Multimedia Integration Language,缩写作 SMIL),是W3C为采用XML描述多媒体而提出的建议标准。(维基百科

动画

  • 非形变动画定义时可以定义多个<animate><animate>

attributeName:指定对哪个参数进行动画设置
from:动画开始时的参数值
to:动画结束时的参数值
dur:动画持续时间,单位可以为:hmsms
begin:什么时候开始执行动画,缺省值为0s
fill:动画最终形态

freeze:保持最后一帧
remove:保持第一帧

repeatCount:动画重复次数,缺省值为1indefinite表示无限重复

1
2
3
4
5
<svg>
<rect x="0">
<animate attributeName="x" from="0" to="10" dur="1s"></animate>
</rect>
</svg>

values:定义一组属性值,属性值之间用;分隔,空格会被忽略,存在values时,fromto无效

1
2
3
4
5
<svg>
<rect x="0">
<animate attributeName="x" values="0;10" dur="1s"></animate>
</rect>
</svg>

在点击时才执行动画

1
2
3
4
5
<svg>
<rect id="id" x="0">
<animate attributeName="x" begin="id.click" to="10" dur="1s"></animate>
</rect>
</svg>

指定动画执行完后再执行的动画

1
2
3
4
5
6
<svg>
<rect x="0">
<animate id="id" attributeName="x" from="0" to="10" dur="1s"></animate>
<animate begin="id.end" to="20" dur="1s"></animate>
</rect>
</svg>

形变动画

  • 形变动画定义时只能定义一个<animateTransform></animateTransform>,如果定义了多个,后定义的会覆盖之前指定的

平移

1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="translate" from="0,0" to="10,10" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="translate" values="0,0;10,10" dur="1s"></animateTransform>
</rect>
</svg>

旋转

1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="rotate" from="0 0 0" to="360 0 0" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="rotate" values="0 0 0;360 0 0" dur="1s"></animateTransform>
</rect>
</svg>

缩放

1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="scale" from="1" to="2" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="scale" from="1 1" to="2 2" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="scale" values="1;2" dur="1s"></animateTransform>
</rect>
</svg>
1
2
3
4
5
<svg>
<rect>
<animateTransform attributeName="transform" type="scale" values="1 1;2 2" dur="1s"></animateTransform>
</rect>
</svg>

运动动画

path:定义运动路径
rotate:定义运动的行进方向

auto:缺省值,自动

1
2
3
4
5
<svg>
<rect>
<animateMotion path="M 0 0, L 0 10, L 10 10, L 10 0" rotate="auto" dur="1s"></animateMotion>
</rect>
</svg>
1
2
3
4
5
6
7
8
<svg>
<path id="id1" d="M 0 0, L 0 10, L 10 10, L 10 0"></path>
<rect id="id2"></rect>

<animateMotion href="#id2" rotate="auto" dur="1s">
<mpath href="#id1"></mpath>
</animateMotion>
</svg>

完成