一、邂逅SVG
1.1 认识SVG
-
SVG 全称为(Scalable Vector Graphics),即可缩放矢量图形。(矢量定义:既有大小又有方向的量。在物理学中称作矢量,如一个带箭头线段:长度表示大小,箭头表示方向;在数学中称作向量。在计算机中,矢量图可无限放大而不变形)
-
SVG 是一种基于XML格式的矢量图,主要用于定义二维图形,支持交互和动画。
-
SVG 规范是万维网联盟(W3C) 自 1998 年以来开发的标准。
-
SVG 图像可在不损失质量的情况下按比例缩放,并支持压缩。
-
基于XML的SVG可轻松的用文本编辑器或矢量图形编辑器创建和编辑,并可以直接在浏览器显示。
1.2 SVG发展史
-
SVG 2.0 版本(推荐)
-
SVG 2.0于2016 年 9 月 15 日成为W3C 候选推荐标准,最新草案于2020年5月26日发布。
-
SVG2.x Change From SVG1.x ( www.w3.org/TR/SVG/chan… ),比如:
- Removed the baseProfile and version attributes from the ‘svg’ element.
- Added the ability to use 'auto' for the width and height attributes on
image. - Added ‘lang’ attribute on ‘desc’ and ‘title’ elements.
- Removed the ‘xlink:type’, ‘xlink:role’, ‘xlink:arcrole’, ‘xlink:show’ and ‘xlink:actuate’ attributes.
- Deprecated the ‘xlink:href’ attribute in favor of using ‘href’ without a namespace.
-
1.3 SVG 优缺点
- 优点
-
扩展好:矢量图像在浏览器中放大缩小不会失真,可被许多设备和浏览器中使用。而光栅图像(PNG 、JPG)放大缩小会失真。
-
矢量图像是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小是不会失真的。
-
光栅图像是由像素点构建的图像——微小的彩色方块,大量像素点可以形成高清图像,比如照片。图像像素越多,质量越高。
-
-
灵活:SVG是W3C开发的标准,可结合其它的语言和技术一起使用,包括 CSS、JavaScript、 HTML 和 SMIL 。SVG图像可以直接使用JS和CSS进行操作,使用时非常方便和灵活,因为SVG也是可集成到 DOM 中的。
-
可以动画:SVG 图像可以使用 JS 、 CSS 和 SMIL 进行动画处理。对于 Web 开发人员来说非常的友好。
-
轻量级:与其它格式相比,SVG 图像的尺寸非常小。根据图像的不同,PNG 图像质量可能是 SVG 图像的 50 倍。
-
可打印:SVG 图像可以以任何分辨率打印,而不会损失图像质量。
-
利于SEO:SVG 图像被搜索引擎索引。因此,SVG 图像非常适合 SEO(搜索引擎优化)目的。
-
可压缩:与其它图像格式一样,SVG 文件支持压缩。
-
易于编辑:只需一个文本编辑器就可以创建 SVG 图像。设计师通常会使用 Adobe Illustrator (AI)等矢量图形工具创建和编辑。
-
- 缺点
-
不适合高清图片制作
-
SVG 格式非常适合用于徽标和图标(ICON)等 2D 图形,但不适用于高清图片,不适合进行像素级操作。
-
SVG 的图像无法显示与标准图像格式一样多的细节,因为它们是使用点和路径而不是像素来渲染的。
-
-
SVG 图像变得复杂时,加载会比较慢
-
1.4 SVG的应用场景
-
SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
-
SVG 适合应用在需适配多种尺寸的屏幕上展示,因为SVG的扩展性更好。
-
当需要创建简单的动画时,SVG 是一种理想的格式。
-
SVG 可以与 JS 交互来制作线条动画、过渡和其他复杂的动画。
-
SVG 可以与 CSS 动画交互,也可以使用自己内置的 SMIL 动画。
-
SVG 也非常适合制作各种图表(条形图、折线图、饼图、散点图等等),以及大屏可视化页面开发。
1.5 SVG 和 Canvas的区别
-
可扩展性:
-
SVG 是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小不会失真。
-
Canvas 是由一个个像素点构成的图形,放大会使图形变得颗粒状和像素化(模糊)。
-
SVG可以在任何分辨率下以高质量的打印。Canvas 不适合在任意分辨率下打印。
-
-
渲染能力:
-
当 SVG 很复杂时,它的渲染就会变得很慢,因为在很大程度上去使用 DOM 时,渲染会变得很慢。
-
Canvas 提供了高性能的渲染和更快的图形处理能力,例如:适合制作H5小游戏。
-
当图像中具有大量元素时,SVG 文件的大小会增长得更快(导致DOM变得复杂),而Canvas并不会增加太多。
-
-
灵活度:
-
SVG 可以通过JavaScript 和 CSS 进行修改,用SVG来创建动画和制作特效非常方便。
-
Canvas只能通过JavaScript进行修改,创建动画得一帧帧重绘。
-
-
使用场景:
-
Canvas 主要用于游戏开发、绘制图形、复杂照片的合成,以及对图片进行像素级别的操作,如:取色器、复古照片。
-
SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
-
二、SVG初体验
2.1 XML 和 DTD 声明
-
由于 SVG 是一个 XML 文件格式。在编写XML文档时,通常是推荐编写XML声明。因为在 XML 1.0 中,XML 声明是可选的,推荐写但不是强制性。然而,在 XML 1.1 中,声明是强制性的,如果没有声明,则自动暗示该文档是 XML 1.0 文档。所以这里建议在编写SVG文件时也编写一个XML 声明。
-
SVG的XML声明格式:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>-
version 指定版本(必填)
-
encoding 指定XML文档的编码(可选,默认是UTF-8)
-
standalone:指定当前 XML 文档是否依赖于外部标记声明(可选,使用该属性时,需和DTD声明一起用才有意义)。
-
no(默认值):代表依赖外部标记声明
-
yes:代表依赖内部默认的标记声明
-
-
-
SVG的文档类型声明(DTD),让解析器验证XML文件是否符合该规范,与HTML5文件的DTD声明类似。
-
XML中内部 DTD 声明(可选)
-
XML中外部 DTD 声明(可选)
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-
2.2 如何创建SVG
-
在一个单独的svg文件中绘制,svg文件可直接在浏览器预览或嵌入到HTML中使用(推荐)
- 第一步:新建一个 svg 文件,在文件第一行编写XML文件声明
- 第二步:编写 一个元素,并给该元素添加如下属性:
- version: 指定使用svg的版本,值为 1.0 和 1.1,并没有 2.0。
- baseProfile:SVG 2 之前,version 和 baseProfile 属性用来验证和识别 SVG 版本。而SVG2后不推荐使用这两个属性了。
- width / height :指定svg画布(视口)的宽和高,默认值分别为300和150,默认使用px单位。
- xmlns:给svg元素绑定一个命名空间
意味着这个
<svg>标签和它的子元素都属于该命名空间下(比如:html中的<title>和svg的<title>可通过命名空间做区分)。
- 第三步:在
<svg>元素中添加 图形(比如:<rect>) 元素 - 第四步:在浏览器直接预览 或 嵌入到 HTML中预览(嵌入HTML有6种方案)
- 1.0版本
<?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"> <!-- version="1.0" baseProfile="full" 正确渲染svg内容时所需要最小SVG语言概述(版本); full:正常的svg语言概述 basic:基本SVG语言概述 tiny: 轻量级SVG语言概述 xmlns: 指定svg元素 和 svg内的子元素都是属于 http://www.w3.org/2000/svg 这个命名空间下 --> <svg version="1.0" baseProfile="full" width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> <title>我是svg title</title> </svg>- 2.0版本
<?xml version="1.0" standalone="no" ?> <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> </svg>
-
直接在HTML文件中使用svg元素来绘制(推荐)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 创建svg 1.0 --> <svg version="1.0" baseProfile="full" width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> </svg> <!-- 创建svg 2.0 --> <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> </svg> <!-- 创建svg 2.0 简写 xmlns="http://www.w3.org/2000/svg" 这个命名空间浏览器的解析器会自动添加 默认w 300px h: 150px --> <svg> <rect x="0" y="0" width="100" height="100"></rect> </svg> </body> </html> -
直接使用JavaScript代码来生成svg矢量图
-
使用AI(Adobe IIIustractor)矢量绘图工具来绘制矢量图,并导出为svg文件(推荐)
2.3 JS创建SVG
-
使用JS脚本来创建SVG时,创建的元素都是需要添加命名空间的
-
比如:创建或者元素都需要添加命名空间(
http://www.w3.org/2000/svg) -
对于元素上的属性如果不带前缀的,命名空间赋值为null
-
-
因为在XML1.1命名空间规范中建议,不带前缀的属性(带前缀xlink:href)命名空间的名称是没有值的,这时命名空间的值必须 使用null值。
-
创建 SVG 常用的 DOM2 API:
- createElementNS(ns,elname):创建SVG元素
- setAttributeNS(ns,attrname,value):给SVG元素添加属性
- getAttributeNS(ns,attrname):获取SVG元素上的属性
- hasAttributeNS(ns, attrname): 判断SVG元素上是否存在某个属性
- removeAttributeNS(ns,attname):删除SVG元素上的某个属性
- 更多的API
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 创建svg2.0 --> <!-- <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> </svg> --> <script> // 1.创建 svg 和 rect 元素 const xmlns = "http://www.w3.org/2000/svg" const svgEl = document.createElementNS(xmlns, 'svg') const rectEl = document.createElementNS(xmlns, 'rect') // 2.给 svg 和 rect 元素对象添加属性 svgEl.setAttributeNS(null, 'version', '1.0') svgEl.setAttributeNS(null, 'width', 100) svgEl.setAttributeNS(null, 'height', 100) rectEl.setAttributeNS(null, 'width', 50) rectEl.setAttributeNS(null, 'height', 50) // 3.将svg添加到body上 svgEl.appendChild(rectEl) document.body.appendChild(svgEl) </script> </body> </html>
2.4 使用SVG的方式
-
img
<!-- 在img中直接使用svg --> <img src="./rect.svg" alt=""> -
background-image
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .box{ width: 200px; height: 200px; background-image: url(./rect.svg); background-repeat: no-repeat; } </style> </head> <body> <div class="box"></div> </body> </html> -
源代码用在html
- 作为HTML 的DOM元素,支持交互,只兼容ie9以上
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="100"></rect> </svg> </body> </html> -
object元素
- 支持交互式 svg,能拿到object的引用,为 SVG 设置动画、更改其样式表等
-
iframe元素
- 支持交互式 svg,能拿到iframe的引用,为 SVG 设置动画、更改其样式表等
-
embed元素
- 支持交互式 svg,能拿到embed的引用,为 SVG 设置动画、更改其样式表等,对旧版浏览器有更好的支持
三、SVG的坐标系统和单位
3.1 坐标系统
-
SVG 使用的坐标系统(网格系统)和 Canvas的差不多。坐标系是以左上角为 (0,0) 坐标原点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。
-
SVG Grid(坐标系)
-
<svg>元素默认宽为 300px, 高为 150px。 -
通常来说网格中的一个单元相当于 svg 元素中的一像素。
-
基本上在 SVG 文档中的 1 个像素对应输出设备(比如显示屏)上的 1 个像素(除非缩放)。
-
<svg>元素和其它元素一样也是有一个坐标空间的,其原点位于元素的左上角,被称为初始视口坐标系 -
<svg>的 transform 属性可以用来移动、旋转、缩放SVG中的某个元素,如<svg>中某个元素用了变形,该元素内部会建立一个新的坐标系统,该元素默认后续所有变化都是基于新创建的坐标系统。
-
3.2 坐标单位
-
SVG坐标系统,在没有明确指定单位时,默认以像素为单位。
- 比如:
<rect x="0" y="0" width="100" height="100" /> - 定义一个矩形,即从左上角开始,向右延展 100px,向下延展 100px,形成一个 100*100 大的矩形。
- 比如:
-
当然也可以手动指明坐标系的单位
四、viewport 和 viewBox
4.1 视口坐标系和用户坐标系
-
视口(viewport)
-
视口是 SVG 可见的区域(也可以说是SVG画布大小)。可以将视口视为可看到特定场景的窗口。
-
可以使用
<svg>元素的width和height属性指定视口的大小。 -
一旦设置了最外层 SVG 元素的宽度和高度,浏览器就会建立初始视口坐标系和初始用户坐标系。
-
-
视口坐标系
-
视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0, 0),x轴正向向右,y轴正向下。
-
初始视口坐标系中的一个单位等于视口中的一个像素,该坐标系类似于 HTML 元素的坐标系。
-
-
用户坐标系( 也称为当前坐标系或正在使用的用户空间,后面绘图都是参照该坐标系 )
-
用户坐标系是建立在 SVG 视口上的坐标系。该坐标系最初与视口坐标系相同——它的原点位于视口的左上角。
-
使用viewBox属性,可以修改初始用户坐标系,使其不再与视口坐标系相同。
-
-
为什么要有两个坐标系?
- 因为SVG是矢量图,支持任意缩放。在用户坐标系统绘制的图形,最终会参照视口坐标系来进行等比例缩放。
4.2 视图框-viewBox
-
视图框(viewBox)
-
viewport是 SVG 画布的大小,而 viewBox 是用来定义用户坐标系中的位置和尺寸 (该区域通常会被缩放填充视口)。
-
viewBox 也可理解为是用来指定用户坐标系大小。因为SVG的图形都是绘制到该区域中。用户坐标系可以比视口坐标系更小或更大,也可以在视口内完全或部分可见。
-
一旦创建了视口坐标系(
<svg>使用width和height),浏览器就会创建一个与其相同的默认用户坐标系。 -
可以使用 viewBox 属性指定用户坐标系的大小。
-
如果用户坐标系与视口坐标系具有相同的高宽比,它将viewBox区域拉伸以填充视口区域。
-
如果用户坐标系和视口坐标系没有相同的宽高比,可用 preserveAspectRatio 属性来指定整个用户坐标系统是否在视口内可见。
-
-
-
viewBox语法
-
viewBox = ,比如:viewBox =' 0 0 100 100'
-
<min-x>和<min-y>确定视图框的左上角坐标(不是修改用户坐标系的原点,绘图还是从原来的 0, 0 开始) -
<width><height>确定该视图框的宽度和高度。-
宽度和高度不必与父元素上设置的宽度和高度相同。
-
宽度和高度负值无效,为 0 是禁用元素的显示。
-
-
-
4.3 视图框-viewBox-相同的宽高比
-
看一个 viewport 和 viewBox 有相同的宽高比的例子:
- 在viewBox属性上设置视图框为视口大小的一半
- 暂时不改变这个视图框左上角,将
<min-x>将<min-y>设置为零 - 视图框的宽度和高度将是视口宽度和高度的一半
-
viewbox="0 0 100 100" 具体做什么的呢?
-
指定画布可显示的区域,用户坐标系从 (0, 0) 的左上点到 (100, 100) 的点,默认单位是px。
-
然后将 SVG 图形绘制到该 viewBox 区域。
-
viewBox区域等比例被放大(放大不会失真)以填充整个视口。
-
用户坐标系映射到视口坐标系,因此——在这种情况下——1个用户单位等于4个视口单位。
-
在 SVG 画布上绘制的任何内容都将相对于该用户坐标系进行绘制 。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body, ul { margin: 0; padding: 0; } body { background-image: url(../images/grid.png); } svg { background-color: rgba(255, 0, 0, 0.1); } </style> </head> <body> <svg width="400" height="400" viewBox="0 0 100 100" > <circle cx="50" cy="50" r="50"></circle> </svg> </body> </html><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body, ul{ margin: 0; padding: 0; } body{ background-image: url(../images/grid.png); } svg{ background-color: rgba(255, 0, 0, 0.1); } </style> </head> <body> <svg width="400" height="400" viewBox="50 50 100 100" > <circle cx="50" cy="50" r="50"></circle> </svg> </body> </html> -
4.4 视图框-viewBox-不同的宽高比
-
在400*400的视口中,viewbox="0 0 200 100" 具体做什么的呢?
-
保留视图框viewBox的宽高比,但视图框viewBox不会拉伸以覆盖整个视口区域。
-
视图框viewBox在视口内垂直和水平居中。
-
-
如何改变视口内的视框位置?
-
给
<svg>添加preserveAspectRatio属性,该属性允许强制统一缩放视图框viewBox- preserveAspectRatio= "none", 强制拉伸图形以填充整个视口
- preserveAspectRatio= “xMinYMin”, 图形在视口的最小x和y轴上显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body, ul{ margin: 0; padding: 0; } body{ background-image: url(../images/grid.png); } svg{ background-color: rgba(255, 0, 0, 0.1); } </style> </head> <body> <svg width="400" height="400" viewBox="0 0 200 100" preserveAspectRatio="xMinYMin" > <circle cx="50" cy="50" r="50"></circle> </svg> </body> </html> -
五、基本图形的绘制
5.1 矩形
-
<rect>元素在屏幕上绘制一个矩形(rect) -
<rect>元素6 个基本属性- x :矩形左上角的 x 轴位置
- y :矩形左上角的 y轴位置
- width :矩形的宽度
- height :矩形的高度
- rx :圆角的 x 轴方位的半径
- ry :圆角的 y 轴方位的半径
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <rect x="0" y="0" width="100" height="50"></rect> <rect x="100" y="100" width="100" height="50" rx="20" ry="20"></rect> </svg>
5.2 圆形
-
<circle>元素会在屏幕上绘制一个圆形 -
<circle>元素有 3 个基本属性- r :圆的半径
- cx :圆心的 x轴位置
- cy :圆心的 y轴位置
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <circle cx="100" cy="100" r="50" fill="skyblue"></circle> </svg>
5.3 椭圆
-
<ellipse>元素是绘制椭圆 -
<ellipse>元素 4 个基本属性- rx :椭圆的 x轴半径,数学上的长轴半径
- ry :椭圆的 y轴半径,数学上的短轴半径
- cx :椭圆中心的 x轴位置
- cy :椭圆中心的 y轴位置
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <ellipse rx="25" ry="50" cx="100" cy="100" fill="blue"></ellipse> </svg>
5.4 直线
-
<line>元素是绘制直线- 它取两个点的位置作为属性,指定这条线的起点和终点位置
- 需描边才能显示,不支持填充和Canvas线条一样
-
<line>元素4 个基本属性- x1 :起点的 x 轴位置
- y1 :起点的 y轴位置
- x2 :终点的 x轴位置
- y2 :终点的 y轴位置
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <line x1="50" y1="50" x2="150" y2="50" stroke="blue" stroke-width="5"></line> </svg>
5.5 折线
-
<polyline>元素是一组连接在一起的直线。- 因为它可以有很多的点,折线的所有点位置都放在一个 points 属性里。
- 默认会填充黑色
-
<polyline>元素1 个基本属性- points : 点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开
- 每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。
- 所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”
- 支持格式: “0 0, 1 1, 2 2”或 “0 ,0 , 1, 1, 2, 2”或 “0 0 1 1 2 2”
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <polyline points="20 0, 50 50, 20 100, 80 100" fill = "transparent" stroke="red"></polyline> <polyline points="80 50 100 90 120 50" fill = "transparent" stroke="blue"></polyline> </svg>
5.6 多边形
-
<polygon>元素是绘制多边形- 和折线很像,它们都是由连接一组点集的直线构成。不同的是,
< polygon>的路径在最后一个点处自动回到第一个点。需要注意的是,矩形也是一种多边形,也可以用多边形创建一个矩形 - 默认会填充黑色
- 和折线很像,它们都是由连接一组点集的直线构成。不同的是,
-
元素1 个基本属性
- points :点集数列。每个数字用空白符、逗号、终止命令或者换行符分隔开
- 每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标
- 点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:“0 0, 1 1, 2 2”
- 路径绘制完后闭合图形,所以最终的直线将从位置 (2,2) 连接到位置 (0,0)
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 三角形 --> <polygon points="20 0, 50 50, 20 100" fill = "green" stroke="blue"></polygon> <!-- 矩形 --> <polygon points="80 20, 160 20, 160 60, 80 60" fill = "transparent" stroke="red"></polygon> </svg>
5.7 路径(path) + 命令
-
<path>元素可能是 SVG 中最常见的形状。可以用<path>元素绘制矩形(直角矩形或圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2 次曲线等曲线。- 默认会填充黑色,默认路径不会闭合
-
<path>元素 1 个基本属性- d :一个点集数列,以及其它关于如何绘制路径的信息,必须M命令开头
- 所以点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:
“M 0 0, 1 1, 2 2” - 支持格式:
“M 0 0, 1 1, 2 2”或“M0 0, 1 1, 2 2”或“M 0 ,0 , 1, 1, 2, 2”或“M 0 0 1 1 2 2”
-
命令
-
<path>元素的形状是通过属性d定义的,属性d的值是一个 “命令 + 参数 ”的序列。 -
每一个命令都用一个关键字母来表示,比如,字母“M”表示的是
“Move to”命令,当解析器读到这个命令时,它就知道是打算移动到某个点。跟在命令字母后面的,是需要移动到的那个点的 x 和 y 轴坐标。比如移动到 (10,10) 这个点的命令,应该写成“M 10 10”命令。这一段字符结束后,解析器就会去读下一段命令。 -
每一个命令都有两种表示方式,
- 大写字母,表示采用绝对定位
- 小写字母,表示采用相对定位(例如:从上一个点开始,向上移动 10px,向左移动 7px)。
-
属性 d采用的是用户坐标系统,不需标明单位。
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 绘制三角形,不闭合 --> <path d="M 20 0, 50 50, 20 100" fill = "transparent" stroke="blue"></path> <!-- 绘制三角形,闭合 --> <path d="M 80 0, 110 50, 80 100 Z" fill = "transparent" stroke="blue"></path> </svg> -
-
d属性值支持的命令
-
直线命令
- M / m:Move To
- L / l :Line To
- Z / z:Close Path
- H / h:horizontal
- V / v:vertical
-
曲线命令
- C :三次贝塞尔曲线
- S:简写三次贝塞尔曲线
- Q:二次贝塞尔曲线
- T:简写二次贝塞尔曲线
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- l: 相对定位 --> <path d="M 20 0,L 80 50,l 20 50 Z" fill="transparent" stroke="red"></path> </svg> -
5.8 image
-
<image>元素的href属性引入图片URL -
注意事项
-
image 元素没设置 x , y 值,它们自动被设置为 0。
-
image 元素没设置 height 、width 时,默认为图片大小。
-
width 、height 等于 0,将不会呈现这个图像。
-
需在 href 属性上引用外部的图像,不是src属性。
<!-- 2.0版本 --> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <image x="0" y="0" width="100" height="100" href="../images/avatar.jpeg" > </image> </svg><!-- 1.0版本 --> <svg version="1.0" baseProfile="full" width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" > <image x="0" y="0" xlink:href="../images/avatar.jpeg" width="100" height="100" > </image> </svg><!-- 2.0 + 1.0版本 --> <svg version="1.0" baseProfile="full" width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" > <image x="0" y="0" xlink:href="../images/avatar.jpeg" href="../images/avatar.jpeg" width="100" height="100" > </image> </svg> -
5.9 text
-
<text>元素是用来在SVG画布中绘制文字 -
<text>元素的基本属性- x 和 y 属性决定了文本在用户坐标系中显示的位置
- text-anchor 文本流方向属性,可以有 start、middle、end 或 inherit 值,默认值 start
- dominant-baseline 基线对齐属性 : 有 auto 、middle 或 hanging 值, 默认值:auto
-
元素的字体属性
-
文本的一个至关重要的部分是它显示的字体。SVG 提供了一些属性,类似于CSS 。下列的属性可以被设置为一个 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 width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 1.在svg中绘制一个文字 --> <!-- <text x="100" y="100" font-size="50" fill="red">Ay</text> --> <!-- 2.文本的对齐方式 --> <!-- <text x="100" y="100" text-anchor="middle" font-size="50" fill="red">Ay</text> --> <!-- 3.基线对齐方式 : 有 auto 、middle 或 hanging 值, 默认值:auto --> <text x="100" y="100" dominant-baseline="middle" font-size="50" fill="red" >Ay</text> </svg> -
5.10 tspan
-
<tspan>元素用来标记大块文本的子部分,它必须是一个text元素或别的tspan元素的子元素。- x 和 y 属性决定了文本在视口坐标系中显示的位置
- alignment-baseline 基线对齐属性:auto 、baseline、middle、hanging、top、bottom ... ,默认是 auto
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 1.在svg中绘制一个文字 --> <text x="40" y="100" font-size="20"> iPhone14 <tspan fill="red">¥100</tspan> </text> </svg>
六、图形的组合和复用
6.1 组合
-
元素的组合
<g>元素是用来组合元素的容器- 添加到g元素上的变换会应用到其所有的子元素上
- 添加到g元素的属性大部分会被其所有的子元素继承
- g元素也可以用来定义复杂的对象,之后可以通过
<use>元素来引用它们
-
元素的属性(该元素只包含全局属性)
-
核心属性:id
-
样式属性:class 、style
-
Presentation Attributes(也可说是 CSS 属性,这些属性可写在CSS中,也可作为元素的属性用):
- cursor, display, fill, fill-opacity, opacity,…
- stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin
- 更多表示属性
-
事件属性:onchange, onclick, ondblclick, ondrag…
-
动画属性:transform
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- <circle cx="50" cy="50" r="30" fill="transparent" stroke="red"></circle> <circle cx="90" cy="50" r="30" fill="transparent" stroke="red"></circle> <circle cx="130" cy="50" r="30" fill="transparent" stroke="red"></circle> <circle cx="170" cy="50" r="30" fill="transparent" stroke="red"></circle> --> <g fill="transparent" stroke="red"> <circle cx="50" cy="50" r="30"></circle> <circle cx="90" cy="50" r="30"></circle> <circle cx="130" cy="50" r="30"></circle> <circle cx="170" cy="50" r="30"></circle> </g> </svg> -
6.2 复用
-
SVG 是允许定义一些可复用元素
-
即把可复用的元素定义在
<defs>元素里面,然后通过<use>元素来引用和显示 -
这样可以增加 SVG 内容的易读性、复用性和利于无障碍开发
-
-
<defs>元素,定义可复用元素-
例如:定义基本图形、组合图形、渐变、滤镜、样式等等
-
在
<defs>元素中定义的图形元素是不会直接显示的 -
可在视口任意地方用来呈现在defs中定义的元素
-
<defs>元素没有专有属性,使用时通常也不需添加任何属性 -
<defs>定义的元素的坐标系参照 用户坐标系
-
-
<use>元素,引入复用元素-
<use>元素从 SVG 文档中获取节点,并将获取到的节点复制到指定的地方 -
<use>等同于深度克隆DOM节点,克隆到use元素所在的位置。 -
克隆的节点是不可见的,当给
<use>元素应用CSS样式时须小心。因为克隆的 DOM 不能保证都会继承<use>元素上的CSS属性,但是CSS可继承的属性是会继承的。
-
-
<use>元素的属性-
href: 需要复制元素/片段的 URL 或 ID(支持跨SVG引用)。默认值:无
-
xlink:href:(SVG2.0已弃用)需要复制的元素/片段的 URL 或 ID 。默认值:无 -
x / y :元素的 x / y 坐标(相对复制元素的位置)。 默认值:0
-
width / height :元素的宽和高(在引入svg或symbol元素才起作用)。 默认值:0
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <defs> <!-- 定义样式 --> <style> rect { fill: blue } </style> <!-- 定义矩形 --> <rect id="rectangle" x="0" y="0" width="100" height="50" fill="red"></rect> <!-- 定义组合图形 --> <g id="logo" fill="transparent" stroke="red"> <circle cx="50" cy="200" r="25"></circle> <circle cx="90" cy="200" r="25"></circle> <circle cx="130" cy="200" r="25"></circle> <circle cx="170" cy="200" r="25"></circle> </g> <!-- 渐变 --> <!-- 滤镜 --> </defs> <!-- 引入复用元素 --> <use href="#rectangle"></use> <!-- 相对于复用元素的位置 --> <use href="#rectangle" x="100" y="100"></use> <use href="#logo"></use> <use href="#logo" x="0" y="60"></use> </svg> -
-
<symbol>元素和<defs>元素类似,也是用于定义可复用元素,然后通过<use>元素来引用显示。-
在
<symbol>元素中定义的图形元素默认也是不会显示在界面上。 -
<symbol>元素常见的应用场景是用来定义各种小图标,比如:icon、logo、徽章等
-
-
<symbol>元素的属性-
viewBox:定义当前
<symbol>的视图框。 -
x / y :symbol元素的 x / y坐标。 ;默认值:0
-
width / height:symbol元素的宽度。 默认值:0
-
-
<symbol>和<defs>的区别-
<defs>元素没有专有属性,而<symbol>元素提供了更多的属性- 比如: viewBox、 preserveAspectRatio 、x、y、width、height等。
-
<symbol>元素有自己用户坐标系,可以用于制作SVG精灵图。- SVG ICON文件-合并成SVG精灵图
-
<symbol>元素定义的图形增加了结构和语义性,提高文档的可访问性。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } body { background-image: url(../images/grid.png); } svg { background-color: rgba(255, 0, 0, 0.1); } </style> </head> <body> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 制作icon --> <symbol id="prev" viewBox="0 0 100 100"> <path d="M 80 0, L 20 50, L 80 100 Z"></path> </symbol> <symbol id="next" viewBox="0 0 100 100"> <polygon points="20 0, 80 50, 20 100"></polygon> </symbol> <!-- 复用 --> <use href="#prev" width="100" height="100"></use> <!-- <use href="#next" width="100" height="100"></use> --> </svg> <!-- 外部复用 --> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- 直接在use上指定icon的 width和 height --> <use href="#prev" width="50" height="50"></use> </svg> <!-- 缩小 --> <svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" > <!-- 直接在use上指定icon的 width和 height --> <use href="#prev"></use> </svg> <!-- 放大 --> <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" > <!-- 直接在use上指定icon的 width和 height --> <use href="#prev"></use> </svg> </body> </html> -
-
制作svg精灵图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 这就是一张SVG精灵图: App.vue 的template中 -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" style="display:none;">
<symbol id="music" viewBox="0 0 1024 1024">
<path fill="#d81e06" d="M512 1024a512 512 0 1 1 512-512 512 512 0 0 1-512 512zm0-992a480 480 0 1 0 480 480A480 480 0 0 0 512 32zm128 640a80 80 0 1 1 48-143.634V416l-224 64v192h-1.61A80.549 80.549 0 1 1 432 592.366V384a32 32 0 0 1 32-32l224-64a32 32 0 0 1 32 32v288h-1.61A80.018 80.018 0 0 1 640 672zm-256-64a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm304-288l-224 64v64l224-64v-64zm-48 224a48 48 0 1 0 48 48 48 48 0 0 0-48-48z"/>
</symbol>
<symbol id="music_1" viewBox="0 0 1024 1024">
<path fill="#d81e06" d="M512 56.89c251.351 0 455.11 203.759 455.11 455.11S763.352 967.11 512 967.11 56.89 763.352 56.89 512 260.648 56.89 512 56.89zm30.037 170.665h-3.185c-13.767 0-24.576 10.468-26.226 23.666-.057.683-.285 1.195-.341 1.878-.058.455-.285.853-.285 1.308v341.618c-14.962-7.964-31.687-12.914-49.778-12.914h-71.111c-58.88 0-106.666 47.787-106.666 106.667S332.23 796.445 391.11 796.445h71.111c58.88 0 106.667-47.787 106.667-106.667 0-2.447-.569-4.722-.74-7.111h.74V305.265l76.345 44.089a28.327 28.327 0 0 0 14.165 3.811c9.842 0 19.4-5.12 24.633-14.222 7.907-13.597 3.243-31.005-10.354-38.912l-116.451-67.186c-4.38-3.072-9.387-5.29-15.19-5.29zM462.223 640c27.42 0 49.777 22.357 49.777 49.778s-22.357 49.777-49.778 49.777h-71.111c-27.42 0-49.777-22.357-49.777-49.776 0-27.422 22.357-49.779 49.777-49.779h71.111z"/>
</symbol>
<symbol id="shouye" viewBox="0 0 1024 1024">
<path fill="#d81e06" d="M981.638 396.91c-.5-.64-1.057-1.196-1.613-1.78L638.747 62.002C605.173 22.225 560.25.362 512.1.362h-.14c-48.26.027-93.267 22.002-126.842 61.946L43.73 394.824a33.308 33.308 0 0 0-1.67 1.78C-5.504 453.822 2.674 495.046 11.77 514.545c9.123 19.5 35.549 52.211 109.93 52.211h38.47v433.962c0 12.85 10.375 23.254 23.198 23.254h654.684c12.823 0 23.198-10.403 23.198-23.254v-430.15c0-12.824-10.375-23.227-23.198-23.227-12.824 0-23.2 10.403-23.2 23.226v406.924H679.249c.139-1.112.64-2.086.64-3.226V756.88c0-90.069-53.547-152.961-130.236-152.961h-75.744c-71.794 0-130.18 58.47-130.18 130.319v240.027c0 1.14.473 2.114.64 3.226H206.566V543.53c0-12.851-10.376-23.255-23.199-23.255H121.7c-35.049 0-60.445-9.513-67.9-25.452-7.343-15.744 1.307-40.945 23.171-67.565l341.333-332.46c.584-.584 1.14-1.168 1.641-1.808 24.73-29.736 57.413-46.147 92.072-46.175h.084c34.52 0 67.148 16.3 91.821 45.924.5.585 1.057 1.197 1.614 1.753l341.194 333.072c21.891 26.62 30.598 51.766 23.282 67.399-7.427 15.855-32.768 25.312-67.844 25.312-12.823 0-23.199 10.404-23.199 23.255 0 12.823 10.376 23.226 23.2 23.226 74.408 0 100.75-32.628 109.873-52.072 9.068-19.443 17.219-60.584-30.403-117.774zM390.125 974.265V734.238c0-46.23 37.58-83.838 83.783-83.838h75.744c50.152 0 83.838 42.781 83.838 106.48v217.385c0 1.14.5 2.114.667 3.226h-244.7c.168-1.112.668-2.086.668-3.226z"/>
</symbol>
</svg>
<!-- Vue 某个子组件 -->
<svg width="50" height="50">
<use href="#music"></use>
</svg>
<svg width="30" height="30">
<use href="#music"></use>
</svg>
<svg width="30" height="30">
<use href="#music_1"></use>
</svg>
<svg width="100" height="100">
<use href="#shouye"></use>
</svg>
<svg width="400" height="400">
<use href="#shouye"></use>
</svg>
</body>
</html>
七、填充和描边
-
要给SVG中的元素上色,一般有两种方案可以实现:
-
第一种:直接使用元素的属性,比如:填充(fill)属性、描边(stroke)属性等
-
在SVG中,绝大多数元素的上色都可通过 fill和stroke 两个属性来搞定。
-
fill属性:设置对象填充颜色。支持:颜色名、十六进制值、rgb、 rgba 。
-
stroke属性:设置绘制对象的边框颜色。支持:颜色名、十六进制值、rgb、 rgba 。
-
-
-
第二种:直接编写CSS样式,因为SVG也是HTML中的元素,也支持用CSS的方式来编写样式。
-
7.1 填充(fill)
-
fill 填充属性,专门用来给SVG中的元素填充颜色
- fill =“color”。支持:颜色名、十六进制值、rgb、 rgba 、 currentColor (继承自身或父亲字体color)。
-
控制填充色的不透明
- fill-opacity = ”number ”, 该属性专门用来控制填充色的不透明,值为 0 到 1。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } body { background-image: url(../images/grid.png); } svg { background-color: rgba(255, 0, 0, 0.1); color: green; } </style> </head> <body> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <defs> <!-- <style> rect{ color: red; } </style> --> </defs> <!-- 基本的使用 --> <!-- <rect x="10" y="10" width="100" height="100" fill="red" fill-opacity="0.4" ></rect> --> <rect x="10" y="10" width="100" height="100" fill="currentColor" ></rect> </svg> </body> </html>
7.2 描边(stroke)
-
stroke = “color”: 指定元素边框填充颜色。
-
stroke-opacity = “number”:控制元素边框填充颜色的透明度。
-
stroke-width = “number”:指定边框的宽度。注意,边框是以路径为中心线绘制的。
-
stroke-linecap =“butt | square | round”:控制边框端点的样式。
-
stroke-linejoin = “miter | round | bevel”:控制两条线段连接处样式
-
stroke-dasharray =“number [, number , ….]”: 将虚线类型应用在边框上。
-
该值必须是用逗号分割的数字组成的数列,空格会被忽略。比如 3,5 :
- 第一个表示填色区域长度为 3
- 第二个表示非填色区域长度为 5
-
-
stroke-dashoffset:指定在dasharray模式下路径的偏移量(将线条往左移动)。
- 值为number类型,除了可以正值,也可以取负值。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } body { background-image: url(../images/grid.png); } svg { background-color: rgba(255, 0, 0, 0.1); } </style> </head> <body> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" > <!-- stroke , 而不是 fill --> <line x1="100" y1="100" x2="200" y2="100" stroke="red" stroke-width="5" stroke-linecap="round" > </line> <polyline points="20 0, 80 50, 20 100" stroke="red" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="transparent" > </polyline> </svg> </body> </html>
八、用CSS编写的方式和优先级别
8.1 编写方式
-
直接编写CSS样式实现填充和描边
-
除了定义元素的属性外,可以通过CSS来实现填充和描边(CSS样式可写在defs中,也可写在HTML头部或外部等)。
-
语法 和 HTML 里使用 CSS 一样,需要注意的是:要把 background-color、border 改成 fill 和 stroke
-
不是所有的属性都能用 CSS 来设置,上色和填充的部分是可以用 CSS 来设置。
- fill,stroke,stroke-dasharray 等可以用CSS设置
- 路径的命令则不能用 CSS 设置
-
-
哪些属性可以使用CSS设置,哪些不能呢?
-
SVG规范中将属性区分成 Presentation Attributes 和 Attributes 属性。
-
Presentation Attributes 属性( 支持CSS和元素用 )
-
Attributes 属性(只能在元素用)
-
-
-
CSS给SVG中的元素填充、描边和上色,支持如下4种编写方式:
- 方式一:内联(行内) CSS 样式,写在元素的style属性上
- 方式二:内嵌(内部) CSS 样式,写在 中的 标签中
- 方式三:内嵌(内部) CSS 样式,写在中的标签中
- 方式四:外部 CSS 样式文件,写在 .css 文件中
8.2 优先级
- 内联的style > defs中的style > 外部 / head内部 > 属性 fill