SVG
0x01 概述
-
SVG(Scalable Vector Graphics,可缩放矢量图)是一种基于 XML 语法的图像格式
-
一般的图片基于像素处理,放大后会失真,而 SVG 是基于对图像的形状描述,放大后不会失真
-
本质上是体积较小的文本文件,比如:
-
SVG 文件
<svg class="icon" style=" width: 1em; height: 1em; vertical-align: middle; fill: currentColor; overflow: hidden; " viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" > <path d="M574.856 64c-247 0-447 200.6-447 448s200 448 447 448c121.2 0 231-48.4 311.6-126.8 10-9.8 12.6-25 6.2-37.4s-20.2-19.4-34-17c-19.6 3.4-39.6 5.2-60.2 5.2-193.8 0-351-157.6-351-352 0-131.6 72-246.2 178.6-306.6 12.2-7 18.4-21 15.4-34.6s-14.6-23.8-28.6-25c-12.6-1-25.2-1.6-38-1.6z" ></path> </svg>
-
SVG 图像预览
-
-
-
SVG 标签是 SVG 图形的一个容器:
<svg></svg>
-
可以理解为画布
-
具有两个重要属性
width
:画布宽度height
:画布高度
<svg width="800" height="600"> <!-- 编辑区 --> </svg>
-
可以通过在 HTML 页面中编辑和预览 SVG 图像:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>SVG</title> </head> <body> <svg width="800" height="600"> <!-- 编辑区 --> </svg> </body> </html>
0x02 形状
-
SVG 有一些预定义的形状元素:
元素 描述 line 线条 polyline 折线(多线条) rect (圆角)矩形 circle 圆形 ellipse 椭圆形 polygon 多边形 path 路径 -
画布的定位是基于二维坐标系
- 坐标原点位于左上角
- 从原点开始,向右为 \(x\) 轴正反向,向下为 \(y\) 轴正方向
- 此坐标系称为“屏幕坐标系”,与“数学坐标系”不同
-
标签
<g></g>
可以为形状成组(group)定义属性
(1)线条
-
标签:
<line />
-
属性:
x1
:\(x\) 轴上的起点坐标y1
:\(y\) 轴上的起点坐标x2
:\(x\) 轴上的终点坐标y2
:\(y\) 轴上的终点坐标opacity
:不透明度,取值范围 0 到 1,值越小越透明stroke
:笔画(详细使用方法在 0x04 描边 说明)
-
举例:
<svg width="100" height="60"> <g stroke="red" stroke-width="4" > <line x1="0" y1="30" x2="100" y2="10" opacity="0.25" /> <line x1="0" y1="30" x2="100" y2="30" opacity="0.5" /> <line x1="0" y1="30" x2="100" y2="50" opacity="0.75" /> </g> </svg>
(2)折线(多线条)
-
标签:
<polyline />
-
属性:
points
:点集,定义折现每个转折点的 \((x,\ y)\) 坐标- 每一对坐标的 \(x\) 和 \(y\) 使用
,
隔开 - 坐标之间使用空格隔开
- 坐标顺序为绘制线条连接的顺序,最后一个坐标连接第一个坐标
- 每一对坐标的 \(x\) 和 \(y\) 使用
-
举例:
<svg width="100" height="75"> <polyline points="0,25 25,25 25,50 50,50 50,25 75,25 75,50 100,50" fill="none" stroke="red" stroke-width="4" /> </svg>
(3)(圆角)矩形
-
标签:
<rect />
-
属性:
width
:矩形宽度height
:矩形高度x
:定义矩形的左边位置y
:定义矩形的顶部位置rx
:矩形 \(x\) 轴圆角半径长度ry
:矩形 \(y\) 轴圆角半径长度fill
:填充颜色,如颜色名称、rgb()
、十六进制颜色值fill-opacity
:填充颜色不透明度,取值范围 0 到 1
-
举例:
<svg width="200" height="150"> <rect width="100" height="75" fill="blue" fill-opacity="0.7" stroke="red" stroke-width="4" x="40" y="30" rx="20" ry="40" /> </svg>
(4)圆形
-
标签:
<circle />
-
属性:
cx
:圆心 \(x\) 坐标cy
:圆心 \(y\) 坐标r
:圆半径
-
举例:
<svg width="200" height="150"> <circle cx="100" cy="75" r="50" fill="blue" stroke="red" stroke-width="4" /> </svg>
(5)椭圆形
-
标签:
<ellipse />
-
属性:
cx
:中心 \(x\) 坐标cy
:中心 \(y\) 坐标rx
:水平半径ry
:垂直半径
-
举例:
<svg width="200" height="150"> <ellipse cx="100" cy="75" rx="50" ry="25" fill="blue" stroke="red" stroke-width="4" /> </svg>
(6)多边形
至少包含三个边
-
标签:
<polygon />
-
属性:
points
:点集,定义多边形每个角的 \((x,\ y)\) 坐标 -
举例:
<svg width="200" height="150"> <polygon points="100,0 0,25 25,100 100,150 175,100 200,25" fill="blue" stroke="red" stroke-width="4" /> </svg>
(7)路径
-
标签:
<path />
-
属性:
d
:(draw)绘制路径的命令-
命令区分大小写
- 大写表示绝对定位,相对坐标原点
- 小写表示相对定位,相对上一个绘制点
-
M x y
:M
是 M 命令(move to),作用是定义绘制图形的起点坐标 \((x,\ y)\) -
l x y
:L
是 L 命令(line to),作用是从上一个绘制点到 \((x,\ y)\) 绘制直线<svg width="200" height="100"> <path d="M 0 100 L 100 0 L 200 50" /> </svg>
-
q x1 y1 x2 y2
:Q
是命令(quadratic Bézier curve),作用是绘制二次贝塞尔曲线,需要控制点坐标 \((x1,\ y1)\) 和终点坐标 \((x2,\ y2)\)<svg width="200" height="160"> <g fill="orange"> <circle cx="40" cy="140" r="3" /> <circle cx="100" cy="20" r="3" /> <circle cx="160" cy="140" r="3" /> </g> <g font-size="20" text-anchor="middle" fill="orange"> <text x="40" y="140" dx="-20">A</text> <text x="100" y="20" dx="-20">B</text> <text x="160" y="140" dx="20">C</text> </g> <g stroke-width="3" fill="none"> <path d="M 40 140 l 60 -120" stroke="red" /> <path d="M 100 20 l 60 120" stroke="red" /> <path d="M 70 80 l 60 0" stroke="green" /> <path d="M 40 140 q 60 -120 120 0" stroke="blue" /> </g> </svg>
-
0x03 文本
-
标签:
-
<text>Text</text>
-
子标签:
<tspan>Sub text</tspan>
- 可以设置文本的不同格式
-
添加链接,如:
<svg xmlns:xlink="http://www.w3.org/1999/xlink"> <a xlink:href="https://example.com" target="_blank"> <text>example.com</text> </a> </svg>
-
-
属性:
x
:\(x\) 轴上的位置坐标y
:\(y\) 轴上的位置坐标dx
:坐标相对 \(x\) 轴正方向偏移量dy
:坐标相对 \(y\) 轴正方向偏移量font-size
:文本大小text-anchor
:文本对齐方式- 取值包括:
start
、middle
、end
- 通过设定 \((x,\ y)\) 相对于文本的位置实现
- 比如,当设置为
middle
时,\((x,\ y)\) 在文本的中间
- 比如,当设置为
- 取值包括:
transform
:文本变换rotate(deg x,y)
:旋转,deg
为旋转角度,x
和y
表示旋转中心点的坐标(默认 \((0,\ 0)\))
-
举例:
<svg width="200" height="100"> <rect width="200" height="100" fill="red" /> <text x="100" y="55" font-size="16" text-anchor="middle" fill="white" transform="rotate(10 100,55)" > Hello, <tspan font-size="24"> SVG </tspan> </text> </svg>
0x04 描边
-
SVG 通过笔画属性实现描边效果,如颜色、宽度、不透明度、线帽、自定义虚线
-
stroke
:笔画颜色,取值为任何合法的颜色值,如颜色名称、rgb()
、十六进制颜色值<svg width="100" height="60"> <g stroke-width="4"> <line x1="0" y1="10" x2="80" y2="10" stroke="red" /> <line x1="0" y1="30" x2="80" y2="30" stroke="rgb(255,0,0)" /> <line x1="0" y1="50" x2="80" y2="50" stroke="#FF0000" /> </g> </svg>
-
stroke-width
:笔画宽度,取值为数字<svg width="100" height="60"> <g stroke="red"> <line x1="0" y1="10" x2="80" y2="10" stroke-width="1" /> <line x1="0" y1="30" x2="80" y2="30" stroke-width="3" /> <line x1="0" y1="50" x2="80" y2="50" stroke-width="5" /> </g> </svg>
-
stroke-opacity
:笔画不透明度,取值在 0 到 1 之间<svg width="100" height="60"> <g stroke="red" stroke-width="4"> <line x1="0" y1="10" x2="80" y2="10" stroke-opacity="0.25" /> <line x1="0" y1="30" x2="80" y2="30" stroke-opacity="0.5" /> <line x1="0" y1="50" x2="80" y2="50" stroke-opacity="0.75" /> </g> </svg>
-
stroke-linecap
:笔画线帽属性,定义开放路径不同类型的结束点,取值有三个:butt
:默认,无线帽round
:圆形线帽square
:方形线帽
<svg width="100" height="60"> <g stroke="red" stroke-width="4"> <line x1="0" y1="10" x2="80" y2="10" stroke-linecap="butt" /> <line x1="0" y1="30" x2="80" y2="30" stroke-linecap="round" /> <line x1="0" y1="50" x2="80" y2="50" stroke-linecap="square" /> </g> </svg>
-
stroke-dasharray
:虚线笔画属性,取值为数字数组(个数 \(\geq 2\)),用于定义线条与间隙大小- 奇数位为线条长度,偶数位为间隙长度
<svg width="100" height="60"> <g stroke="red" stroke-width="4"> <line x1="0" y1="10" x2="80" y2="10" stroke-dasharray="10,5" /> <line x1="0" y1="30" x2="80" y2="30" stroke-dasharray="10,10,5" /> <line x1="0" y1="50" x2="80" y2="50" stroke-dasharray="5,5,10,10" /> </g> </svg>
-
-
笔画属性可以应用于所有形状与文本
0x05 效果
-
通过
<filter></filter>
标签实现模糊和阴影效果- 其中可以包含一个或多个效果滤镜
- 必要属性
id
用于标识过滤器,从而被形状使用 - 其父元素为
<defs></defs>
,defs 是 definitions 的简写
<svg> <defs> <filter id="cusFilter"></filter> </defs> <rect filter="url(#cusFilter)" /> </svg>
(1)模糊
-
高斯模糊效果可以通过
feGaussianBlur
滤镜实现<svg width="100" height="60"> <defs> <filter x="0" y="0" id="filter-blur"> <feGaussianBlur /> </filter> </defs> </svg>
-
模糊效果滤镜属性
stdDeviation
:定义模糊数量,值越大越模糊<svg width="120" height="70"> <defs> <filter x="0" y="0" id="filter-blur"> <feGaussianBlur stdDeviation="10" /> </filter> </defs> <g fill="blue" stroke="red" stroke-width="4"> <circle cx="30" cy="30" r="25" filter="url(#filter-blur)" /> <circle cx="90" cy="30" r="25" /> </g> </svg>
(2)阴影
-
阴影效果的原理:将图形复制并相对原图形偏移
-
阴影效果可以通过
feOffset
和feBlend
滤镜实现 -
<feOffset />
用于偏移图形,其属性包括:dx
:阴影在 \(x\) 轴上的偏移量dy
:阴影在 \(y\) 轴上的偏移量in
:阴影图形来源,取值如下SourceAlpha
:黑色阴影SourceGraphic
:原图形
-
<feBlend />
用于在偏移的图形上混合原始图形,其属性需要in=SourceGraphic
-
举例:
<svg width="120" height="80"> <defs> <filter x="0" y="0" id="filter-shadow"> <feOffset dx="10" dy="10" in="SourceAlpha" /> <feGaussianBlur stdDeviation="10" /> <feBlend in="SourceGraphic" /> </filter> </defs> <g fill="blue" stroke="red" stroke-width="4"> <circle cx="30" cy="30" r="25" filter="url(#filter-shadow)" /> <circle cx="90" cy="30" r="25" /> </g> </svg>
0x06 渐变
- 渐变是指从一种颜色到另一种颜色的平滑过渡
- 可以是两个或多个颜色之间渐变
- SVG 渐变分为线性渐变和径向渐变
(1)线性
-
线性渐变包括水平渐变、垂直渐变、角度渐变
-
在
<defs></defs>
中使用<linearGradient></linearGradient>
实现 -
linearGradient
标签属性:id
:标识渐变设置,从而被形状使用x1
:\(x\) 轴上的起点坐标y1
:\(y\) 轴上的起点坐标x2
:\(x\) 轴上的终点坐标y2
:\(y\) 轴上的终点坐标
- 当 \(y1 = y2\) 且 \(x1 \neq x2\) 时,是水平渐变
- 当 \(x1 = x2\) 且 \(y1 \neq y2\) 时,是垂直渐变
-
渐变过程中的每个颜色使用
<stop />
指定 -
stop
标签属性:offset
:定义渐变颜色的结束位置,取值为相对位置的百分比stop-color
:定义渐变的颜色
-
举例:
<svg width="100" height="60"> <defs> <linearGradient id="lg" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" stop-color="red" /> <stop offset="16%" stop-color="orange" /> <stop offset="32%" stop-color="yellow" /> <stop offset="48%" stop-color="green" /> <stop offset="64%" stop-color="blue" /> <stop offset="80%" stop-color="cyan" /> <stop offset="96%" stop-color="purple" /> </linearGradient> </defs> <ellipse cx="50" cy="30" rx="45" ry="25" fill="url(#lg)" /> </svg>
(2)径向
-
在
<defs></defs>
中使用<radialGradient></radialGradient>
实现 -
radialGradient
标签属性:id
:标识渐变设置,从而被形状使用cx
、cy
:定义外圆的中心坐标fx
、fy
:定义内圆的中心坐标r
:定义外圆半径
-
径向渐变的颜色也用
<stop />
标签指定 -
举例:
<svg width="100" height="60"> <defs> <radialGradient id="rg" cx="50%" cy="50%" fx="50%" fy="50%" r="50%"> <stop offset="0%" stop-color="red" /> <stop offset="96%" stop-color="orange" /> </radialGradient> </defs> <ellipse cx="50" cy="30" rx="45" ry="25" fill="url(#rg)" /> </svg>
-End-