前言
首先,毫无疑问,这是一份非常完善且简洁的SVG学习教程
它包含了SVG所有的核心内容,而且有说明和示例
对于更复杂的细节,最后附有官方文档,我们一般也用不上
SVG版本说明
SVG1.1包含了SVG所有的基本用法
SVG2.0扩充了更多的动态编程属性
相对而言,SVG2.0的扩展部分,是比SVG1.1基础部分要复杂的
不过我们一般也不用手动去编写SVG脚本,会有专业编辑器帮我们去生成
SVG语法说明
这里我们不再区分哪个标签是1.1版本的,哪个标签是2.0版本的
因为现在的SVG渲染引擎,几乎都支持2.0版本语法,没必要刻意去区分
SVG根标签
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="600" height="600">
</svg>
这里通过width和height来指定SVG整个图片的宽高
对于子标签,还能使用百分比作为元素宽高
viewport属性
通过宽高来指定图片尺寸,图片左上角坐标为[0, 0],右下角坐标为[width, height]
如果不想以[0, 0]作为左上角的坐标,可以通过viewBox来定义图片坐标范围
viewBox包含四个参数,分别是左上角坐标,和图片宽高
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="-600 -600 1200 1200">
</svg>
基本图形元素
- 矩形,rect
- 圆形,circle
- 椭圆,ellipse
- 直线,line
- 多边形,polygon
- 多段线,polyline
- 路径,path,最强大最核心的元素,下面会单独讲解
- 分组,g,将多个元素包含到一个容器元素里面,以便对多个元素进行整体操作,或提升可读性
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="-600 -600 1200 1200">
<rect width="50%" height="50%" fill="#EEEE0022"/>
<circle cx="100" cy="100" r="50" fill="blue" stroke="black" stroke-width="2" />
</svg>
通用属性
-
id,元素id,用于元素间关联,或提升可读性
-
width/height,元素宽高
-
x/y,起始坐标,不指定时默认为0
-
cx/cy,中心坐标
-
r,半径
-
rx/ry,圆角半径或椭圆半径
-
fill/stroke/stroke-width,填充色,描边色,描边宽度
-
x1/x2/y1/y2,两个点的坐标
-
points,多个点的坐标,格式为points=“x1,y1 x2,y2 x3,y3”
-
d,指定路径数据,参考格式如d=“M x1 y1 L x2 y2 … Z”
-
不少size属性都可以使用百分比来表示
-
有的百分比相对于图片大小,有的相对于自身大小,可以自己去尝试下效果
-
stroke-dasharray,虚线长度数组,数组可为任意长度,首个数值为实线长度,下个数值为虚线,依此循环
-
stroke-dashoffset,虚线数组偏移一定距离,从指定位置offset开始显示
SVG路径
SVG通过定义一系列运动指令,来绘制任意的自定义路径
- M,移动到指定点,但不绘制移动路径
- L,画一条直线到指定点,指定终点坐标
- H,画一条水平线到指定点,指定x即可
- V,画一条垂直线到指定点,指定y即可
- C,画一条三次贝塞尔曲线到指定点,指定两个控制点坐标,和终点坐标
- S,画一条对称三次贝塞尔曲线到指定点,只需指定一个控制点,会自动使用对称点作为另一个控制点
- Q,画一条二次贝塞尔曲线到指定点,指定控制点坐标,和终点坐标
- T,画一条对称二次贝塞尔曲线到指定点,指定终点坐标即可
- T一般接在Q或T后面使用,会自动推断控制点,来画一条和前段曲线对称的下一段曲线
- T单独使用时,将会以终点作为控制点,画出的是直线
- Z,闭合路径,画一条连接当前点与起点的路径
- 重复指令,当一个指令需要执行多次,但坐标不同时,可以省略重复指令,直接指定多组坐标即可
- 相对位置,以上指令符大写时,表示绝对坐标,如果用小写,则表示相对于当前位置的相对坐标
- A,以当前位置为起点,画一条到终点的弧形
- 弧形指令需要的参数比较多,下一节我们专门来讲解
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="0 0 600 600">
<path id="AB" d="M 100 350 l 150 -300" stroke="red" stroke-width="3" fill="none"/>
<path id="BC" d="M 250 50 l 150 300" stroke="red" stroke-width="3" fill="none"/>
<path id="Curve" d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none"/>
</svg>
Arc指令参数
- 弧形半径rx/ry
- 短轴方向x-axis-rotation,度数为单位
- 取短弧还是长弧,large-arc-flag,1表示取长弧,0表示取短弧
- 顺时针方向还是逆时针方向,sweep-flag,1表示顺时针到终点,0表示逆时针到终点
- 终点坐标x/y
- 给定起点和终点,给点弧长,给定中心轴方向,可能的弧形有四种,正好对应large-arc-flag和sweep-flag的四种组合
- 可以通过以下模拟代码,来熟悉其使用效果
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#FFFF0011"/>
<path d="M 75 75 A 50 50 0 0 0 125 125" fill="transparent" stroke="red" stroke-width="2"/>
<path d="M 75 75 A 50 50 0 0 1 125 125" fill="transparent" stroke="green" stroke-width="2"/>
<path d="M 75 75 A 50 50 0 1 1 125 125" fill="transparent" stroke="blue" stroke-width="2"/>
<path d="M 75 75 A 50 50 0 1 0 125 125" fill="transparent" stroke="purple" stroke-width="2"/>
<path d="M 75 75 L 125 125" fill="transparent" stroke="black" stroke-width="2" stroke-dasharray="1 3" stroke-dashoffset="1"/>
</svg>
文字
文字通过text标签创建,主要参数为
-
x/y,位置
-
font-size,字体大小
-
font-family,字体
-
text-anchor,文字相当于给定位置的对齐方式
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<text x="100" y="100" font-family="Arial" font-size="20" fill="blue" text-anchor="middle">Hello, SVG!</text>
</svg>
图像
SVG可以通过image标签来嵌入图像
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="400">
<image href="https://img-home.csdnimg.cn/images/20230308042836.png"/>
</svg>
图案
SVG通过pattern标签来定义一个图案
图案可以由多个子元素组合而成,并且可以按一定方式重复显示,作为其它元素的填充材料
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<linearGradient id="Gradient1">
<stop offset="5%" stop-color="white"/>
<stop offset="95%" stop-color="blue"/>
</linearGradient>
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="5%" stop-color="red"/>
<stop offset="95%" stop-color="orange"/>
</linearGradient>
<pattern id="Pattern"
x="0" y="0" width=".25" height=".25"
patternUnits="objectBoundingBox">
<rect x="0" y="0" width="50" height="50" fill="skyblue"/>
<rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
<circle cx="25" cy="25" r="20"
fill="url(#Gradient1)"
fill-opacity="0.5"/>
</pattern>
<rect x="0" y="0" width="200" height="200"
fill="url(#Pattern)" stroke="black"/>
</svg>
高级标签
以上是SVG的核心内容,到此为止,我们基本已经知道SVG是怎样一种使用方式
下面我们通过实例的方式,来演示高级标签的使用方法
并且,我将不再讲述具体参数的含义
从属性单词和运行效果,很容易知道参数的实际含义,没必要像背书一样去讲解
线性渐变
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="red"/>
<stop offset="100%" stop-color="blue"/>
</linearGradient>
<rect x="50" y="50" width="100" height="80" fill="url(#gradient)"/>
</svg>
放射渐变
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="100%" fy="50%">
<stop offset="0%" stop-color="red"/>
<stop offset="100%" stop-color="blue"/>
</radialGradient>
<circle cx="100" cy="100" r="80" fill="url(#gradient)"/>
</svg>
裁剪效果
SVG允许通过clipPath标签,来定义一个显示范围裁剪效果
默认显示范围,为clipPath下所有元素范围的总和
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<rect x="0" y="0" width="200" height="200" fill="#FFFF0011"/>
<clipPath id="clip">
<circle cx="100" cy="50" r="50"/>
<rect x="0" y="0" width="100" height="100"/>
</clipPath>
<circle cx="100" cy="100" r="100" fill="#00FFFF33" clip-path="url(#clip)"/>
</svg>
遮罩效果
SVG允许通过mask标签,来定义一个半透明的图层,叠加在当前元素上面
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<linearGradient id="gradient">
<stop offset="0%" stop-color="white" stop-opacity="50%"/>
<stop offset="100%" stop-color="white" stop-opacity="80%"/>
</linearGradient>
<mask id="mask">
<rect x="0" y="0" width="200" height="200" fill="url(#gradient)"/>
</mask>
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#mask)"/>
</svg>
滤镜效果
SVG提供了以下滤镜效果
- 阴影效果,Shadow
- 模糊效果,Blur
- 亮度调整,Brightness
- 对比度调整,Contrast
- 颜色变换,Color Matrix
- 图像混合,Blend Mode
阴影效果
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<filter id="shadow_filter">
<feDropShadow dx="2" dy="2" stdDeviation="3" flood-color="gray" flood-opacity="0.9"/>
</filter>
<rect x="50" y="50" width="100" height="80" fill="red" filter="url(#shadow_filter)"/>
</svg>
模糊效果
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<filter id="blur_filter">
<feGaussianBlur in="SourceGraphic" stdDeviation="5 5"/>
</filter>
<rect x="100" y="100" width="200" height="200" fill="red" filter="url(#blur_filter)"/>
</svg>
坐标转换
SVG提供了transform属性,用于对元素进行转换,包括以下方式
- 平移变换,translate,需提供dx/dy两个参数
- 旋转变化,rotate,需提供degree/cx/cy三个参数
- 缩放变换,scale,需提供sx/sy两个参数,注意,scale是针对整个画布的,x/y也会被一起缩放
- 斜切变换,skewX,skewY,需提供一个degree参数,skew也是针对整个画布的,x/y也会被一起缩放
- 矩阵变换,通过一个2×3的矩阵,对初始坐标进行转换
- 矩阵转换公式为
- newX = ax + cy + e
- newY = bx + dy + f
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="300" height="100">
<rect width="100%" height="100%" fill="#FFFF0011"/>
<rect x="25" y="25" width="50" height="50" fill="#003333AA"
transform="scale(1.2,0.8) rotate(20,50,50) translate(30,0) skewX(10) skewY(10)"/>
</svg>
矩阵变换
矩阵变换需要提供六个参数,分别代表
- a,scaleX
- b,skewY
- c,skewX
- d,scaleY
- e,translateX
- f,translateY
- 注意,这里的skew不再是斜切度数,而是最终的坐标转换系数
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<rect
width="100%"
height="100%"
fill="#FFFF0011"/>
<rect
x="10"
y="10"
width="30"
height="20"
fill="#FF00FF22"/>
<rect
x="10"
y="10"
width="30"
height="20"
fill="#00FFFF22"
transform="matrix(3 1 1 3 30 40)"/>
</svg>
定义可复用对象
defs标签,可以包含若干元素,这些元素可以被其它地方引用或复用
defs标签下的元素,在被复用前,都不会被展示
复用通过use标签来实现,引用通过#来连接其id
<svg width="100" height="100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="C" r="10"/>
<filter id="BF">
<feGaussianBlur in="SourceGraphic" stdDeviation="1 1"/>
</filter>
</defs>
<style>
#C1 { fill:red }
#C2 { fill:green }
#C3 { fill:blue; filter:url(#BF) }
</style>
<use id="C1" x="50" y="20" xlink:href="#C"/>
<use id="C2" x="50" y="50" xlink:href="#C" filter="url(#BF)"/>
<use id="C3" x="50" y="80" xlink:href="#C"/>
</svg>
动画
SVG允许通过animate标签,来为指定属性添加动画
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<rect width="100%" height="100%" fill="#FF00FF11">
<animate
attributeName="rx"
values="30%;50%;30%"
dur="3s"
repeatCount="indefinite"/>
</rect>
</svg>
CSS样式
在SVG中,也可以像HTML一样,通过style标签,或style属性,来设置元素样式
上面的代码已经使用到了该特性
Script脚本
类似于对CSS的支持,SVG也支持Script脚本,并且可以通过onclick等属性调用脚本函数
<svg xmlns='http://www.w3.org/2000/svg' width="200" height="200">
<script type="text/ecmascript">
function reshape(event) {
var element=event.target
var rx = element.getAttribute ("rx")
if(rx=="50%"){
element.setAttribute ("rx", "0%")
}else{
element.setAttribute ("rx", "50%")
}
}
</script>
<rect onclick="reshape(evt)" width="100%" height="100%" fill="#FF00FF11"/>
</svg>
参考文档
https://www.w3.org/TR/SVG
https://www.w3.org/TR/SVG/coords.html
https://developer.mozilla.org/zh-CN/docs/Web/SVG