svg 是 Scalable Vector Graphics(可缩放矢量图形)的简称,它是一种基于 XML 格式(XML 是区分大小写的)的矢量图。创建 svg 图形的方法有很多,可以直接创建一个 svg 文件,也可以在 html 文件中使用 svg
元素来绘制,还可以使用 js 来生成,或者使用 Adobe Illustrators 等软件直接绘制好图形后导出 svg 文件。
直接创建 svg 文件
我们可以从阿里的图标库选择一个图标,然后点击 "SVG下载" 去获取一个 svg 文件,看看别人怎么写的:
它可能长成下面这样子:
文件的第一行 <?xml version="1.0" standalone="no"?>
为 XML 声明,version
用于指定版本,standalone="no"
表示当前文档不是独立的,而是有依赖外部文件,这个外部文件会在下一行的 DTD 中定义。其实还有个指定编码格式的 encoding
属性被省略了,其默认为 encoding="UTF-8"
。
第二行的 <!DOCTYPE svg ...
是 DTD(Document Type Definition),即文档类型声明,用于让解析器验证 XML 是否符合相应规范。!DOCTYPE
后的 svg
代表文件的内容部分的根元素为 svg
,"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
为依赖的外部 DTD 文件的文件名。当我们新建 html 文件时,第一行的 <!DOCTYPE html>
也就是 DTD,表明文件的根元素为 html
。
事实上,XML 声明和 DTD,都可以省略不写,浏览器解析器会帮我们自动加上。
第三行 svg
元素的属性中定义了多个属性:
viewBox
:用于修改 svg 的用户坐标系,之后会单独写一篇文章详细介绍;version
:它的值可以是1.0
或1.1
,用于指定 SVG 的版本。大体上,svg 可以划分为 2 个版本:1.x 和 2.x,它们的写法有些不同。比如 SVG 2 中,svg
元素上的version
和baseProfile
属性,就被删除了,也就是说如果不写version
,即代表是 SVG 2;xmlns
: 用于指定命名空间,它的值看起来像个链接,但其本意只是一个具有唯一性的字符串。有了命名空间,则该<svg>
和它的子元素就都位于这个命名空间下,避免出现某个标签(比如 XHTML 和 SVG 都有一个<title>
标签)不知道是属于谁的问题;xmlns:xlink
:是一个 XML 命名空间声明,它定义了xlink
为前缀的元素和属性在XML文档中的命名空间,比如在 SVG1.x 版本中使用图片,<image xlink:href="./前进.svg"></image>
中的href
属性,就有个xlink
前缀,表明href
属性属于 W3C xlink 命名空间,它的值要遵循相应规范。在 SVG2 中,建议直接使用href
即可,不需要带上xlink
前缀;width
/height
:用于指定 svg 的视口坐标系的宽高,默认值为300
和150
,不用写单位,默认为px
。
综上所述,我们自己直接通过创建一个 svg 文件来生成 SVG2,最简单的写法如下:
svg
<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100"></rect>
</svg>
在浏览器打开效果如下:
在 html 中引用
在 html 中引用外部的 svg 文件,可以像使用图片那样使用,比如比较常见的 2 种方式是:
- 通过
<img>
标签引入:<img src="./前进.svg" alt="" />
; - 通过背景图片引入:
html
<style>
.bg {
width: 100px;
height: 100px;
background-image: url('./前进.svg');
background-size: cover;
}
</style>
<div class="bg"></div>
在 html 文件中使用 svg 元素
我们也可以直接在 html 文件中通过 <svg>
元素来绘制图形:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>探究svg</title>
<style>
svg {
border: 1px solid red;
}
</style>
</head>
<body>
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100"></rect>
</svg>
</body>
</html>
因为没有给 <svg>
添加 version
属性,所以使用的版本是 SVG2,我还在 <style>
中直接给 <svg>
本身添加上了红色边框样式,效果如下:
<svg>
里的 width
和 height
如果为默认值,可以省略不写,xmlns
也可以省略不写,浏览器解析器会自动添加:
html
<body>
<svg>
<rect width="100" height="100"></rect>
</svg>
</body>
通过 js 创建 svg
原生 js 创建
前面介绍的创建 svg 的方法中,我们通过 <svg>
的 xmlns
来指定了命名空间,在用 js 创建 svg 时,所有的元素也都需要添加命名空间,其方式是使用为解决原本的 DOM1 API 无法定义命名空间这一问题而推出的 DOM2 API:
所谓的 DOM2 API,其作用和去掉 NS
后的同名的 DOM1 API 是等效的,比如createElementNS
的作用和 createElement
一样都是用来创建元素的,只不过 DOM2 API 的第一个参数为命名空间,对于像 width
这样不带前缀的属性,命名空间就赋值为 null
。代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>探究svg</title>
<style>
svg {
border: 1px solid red;
}
</style>
</head>
<body>
<script>
window.onload = function () {
// 命名空间
const xmlns = 'http://www.w3.org/2000/svg'
// 定义 svg
const svg = document.createElementNS(xmlns, 'svg')
// 定义 rect
const rect = document.createElementNS(xmlns, 'rect')
rect.setAttributeNS(null, 'width', 200)
rect.setAttributeNS(null, 'height', 100)
// 添加到 dom 中
svg.appendChild(rect)
document.body.appendChild(svg)
}
</script>
</body>
</html>
创建后效果如下:
使用 Snap.svg 创建
直接使用原生 js 处理 svg 比较麻烦,如果真想通过 js 来创建或处理 svg,可以使用 Snap.svg(类似于 jQuery )这个库:
html
<script src="../js/snap.svg-min.js"></script>
<script>
window.onload = function () {
// 定义 svg
const svg = Snap(300, 300)
// 定义 rect
const rect = svg.rect(0, 0, 200, 200)
// 给 rect 添加属性
rect.attr({
fill: 'red'
})
// 添加到 dom 中
document.body.appendChild(svg.node)
}
</script>
直接通过 Snap()
创建 svg
,可以传入宽高值指定 svg 的大小,如果不传则默认大小为 300px * 150px。Snap()
还可以传入其它类型的参数,例如传入选择器以获取已经创建的 svg:Snap('#my-canvas')
。
创建基本形状有着对应的方法,比如也是创建矩形,就直接使用 svg.rect()
,传入的参数为矩形的 x
、y
和宽高值。如果想给矩形添加属性可以通过 rect.attr()
传入对象。 最后将 svg.node
添加到 dom 中,因为得到的 svg
本身是个对象而不是直接就是 <svg>
元素:
效果如下:
通过 Adobe Illustrators 绘制
可以使用绘图软件 AI 直接绘制好图形,然后选择"文件 - 导出 - 导出为..." (也可以选择"导出为多种屏幕所用格式")
然后在保存文件时选择类型为 SVG:
这样导出得到的 svg 文件,代码示例如下:
html
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 161 103">
<rect x=".5" y=".5" width="160" height="102"/>
<path d="M160,1V102H1V1H160m1-1H0V103H161V0h0Z"/>
</svg>