一、邂逅SVG
1. 什么是SVG
- SVG,可缩放矢量图形。(矢量:既有大小又有方向的量。在物理学中称作矢量;在数学中称作向量。)
- SVG是一种基于XML格式的矢量图,主要用于定义二维图形,支持交互和动画。
- SVG图像可在不损失质量的情况下按比例缩放,并支持压缩。
- 基于XML的SVG可轻松的用文本编辑器或矢量图形编辑器创建和编辑,可以直接在浏览器显示。
2. SVG应用场景
- 非常适合显示矢量徽标(logo)、图标(Icon)和其他几何设计;
- 适合应用在需适配多种尺寸的屏幕上显示,因为SVG的扩展性更好;
- 简单的动画;
- 适合制作各种图表,以及大屏可视化页面开发。
3. SVG优缺点
- 优点
- 扩展好:矢量图像在浏览器中放大缩小不会失真,可被许多设备和浏览器使用;而光栅图像(PNG、JPG)放大缩小会失真。
- 矢量图像是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小是不会失真的。
- 光栅图像是由像素点构成的图像——微小的彩色方块,大量像素点可以构成高清图像。图像像素越多,质量越高。
- 灵活:SVG图像可以直接使用JS和CSS进行操作,使用时非常方便和灵活,因为是SVG也是可集成到DOM中的。
- 可以动画:SVG图像可以使用JS、CSS和SMIL进行动画处理。
- 轻量级:与其他格式相比,SVG图像的尺寸非常小。
- 可打印:SVG图像可以以任何分辨率打印,而不会损失图像质量。
- 利于SEO:SVG图像被搜索引擎索引。因此,SVG图像非常适合SEO目的。
- 可压缩:与其他图像格式一样,SVG文件支持压缩。
- 易于编辑:只需一个文本编辑器就可以创建SVG图像。
- 扩展好:矢量图像在浏览器中放大缩小不会失真,可被许多设备和浏览器使用;而光栅图像(PNG、JPG)放大缩小会失真。
- 缺点
- 不适用于高清图片制作;
- SVG图像变得复杂时,加载会比较慢;
- 不完全扩平台。
4. SVG和Canvas的区别
- 可扩展性
- SVG是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小不会失真。
- Canvas是由一个个像素点构成的图形,放大会使图形变得颗粒化和像素化(模糊)。
- SVG可以在任何分辨率下以高质量的打印;Canvas不适合在任意分辨率下打印。
- 渲染能力
- 当SVG很复杂时,它的渲染就会变得很慢,因为在很大程度上去使用DOM时,渲染会变得很慢。
- Canvas提供了高性能的渲染和更快的图形处理能力。
- 当图像中具有大量元素时,SVG文件的大小会增长得更快,而Canvas并不会增加太多。
- 灵活度
- SVG可以通过JavaScript和CSS进行修改,用SVG来创建动画和制作特效非常方便。
- Canvas只能通过JavaScript进行修改,创建动画得一帧帧重绘。
- 使用场景
- Canvas主要用于游戏开发、绘制图形、复杂照片的合成,以及对图片进行像素级别的操作。
- SVG非常适合显示矢量徽标(logo)、图标(Icon)和其他几何设计。
5. 初体验SVG
- 绘制SVG矢量图的方式
- 在单独的svg文件中绘制,svg文件可直接在浏览器预览或嵌入到HTML中使用;
- 直接在HTmL文件中使用svg元素来绘制;
- width/height —— svg画布的宽和高,默认值分别为300和150;
- xmlns —— 给svg元素绑定一个命名空间(www.w3.org/2000/svg)
- 直接使用JavaScript代码来生成svg矢量图;
- createElementNs(ns, elname)
- setAttributeNs(ns, attrname, value)
- getAttributeNs(ns, attrname)
- hasAttributeNs(ns, attrname)
- removeAttributeNs(ns, attrname)
- 使用AI矢量绘图工具来绘制矢量图,并导出为svg文件。
- XML和DTD声明
- SML声明格式:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
- version —— 指定版本
- encoding —— 指定XML文档的编码
- standalone —— 指定XML文档是否依赖于外部标记声明
- DTD声明:
<!DOCTYPE svg PUBLIC "-//W3C/DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
- SML声明格式:
- SVG使用方式
- img元素
- CSS背景
- 直接在HTML文件作为HTML的DOM元素引用
- object元素
- iframe元素
- embed元素
6. 认识SVG网络和坐标系统
- 坐标系是以左上角(0, 0)为坐标原点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下。
7. 视口 - viewport
- 什么是视口
- 视口是SVG可见的区域(也可以说是SVG画布的大小)。可以将视口视为可看到特定场景的窗口。
- 可以使用svg元素的width和height属性指定视口的大小。
- 一旦设置了最外层SVG元素的宽度和高度,浏览器就会建立初始视口坐标系和初始用户坐标系。
- 视口坐标系
- 视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0, 0),x轴正向向右,y轴正向向下。
- 用户坐标系
- 用户坐标系是建立在SVG视口上的坐标系。该坐标系最初与视口坐标系相同——它的原点位于视口的左上角。
- 使用viewBox属性,可以修改初始用户坐标系,使其不再与视口坐标系相同。
SVG是矢量图,支持任意缩放。在用户坐标系统绘制的图形,最终会参照视口坐标系来进行等比例缩放。
7. 视图框 - viewBox
- viewport是SVG画布的大小,而viewBox是用来定义用户坐标系统的位置和尺寸。
- viewBox = "x y width height"
- 如果用户坐标系与视口坐标系具有相同的宽高比,它将viewBox区域拉伸以填充视口区域。
- 如果用户坐标系和视口坐标系没有相同的宽高比,可用preserveAspectRatio属性来指定整个用户坐标系统是否在视口内可见。
二、绘制基本形状
1. 绘制矩形(rect)
- rect元素的基本属性
- x:矩形左上角的x轴位置
- y:矩形左上角的y轴位置
- width:矩形的宽度
- height:矩形的高度
- rx:圆角的x轴方位的半径
- ry:圆角的y轴方位的半径
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="100" height="50"></rect> <rect x="100" y="100" width="100" height="50" rx="20" ry="10"></rect> </svg>
2. 绘制圆形(circle)
- circle元素的基本属性
- r:圆的半径
- cx:圆心的x轴位置
- cy:圆心的y轴位置
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <circle cx="100" cy="100" r="50"></circle> </svg>
3. 绘制椭圆(ellipse)
- ellipse元素的基本属性
- rx:椭圆的x轴半径
- ry:椭圆的y轴半径
- cx:椭圆中心的x轴位置
- cy:椭圆中心的y轴位置
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="100" cy="100" rx="25" ry="50" fill="green"></ellipse> </svg>
4. 绘制线条(line)
- line元素的基本属性
- x1:起点的x轴位置
- y1:起点的y轴位置
- x2:终点的x轴位置
- y2:终点的y轴位置
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <line x1="100" y1="100" x2="200" y2="100" stroke="red" stroke-width="5"></line> </svg>
5. 绘制折线(polyline)
- polyline元素的基本属性
- points:点集数列
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <!-- 1. 第一种写法(推荐) --> <!-- <polyline points="20 0, 80 50, 20 100"></polyline> --> <polyline points="20 0, 80 50, 20 100" fill="transparent" stroke="red"></polyline> <!-- 2. 第二种写法 --> <!-- <polyline points="20 0 80 50 20 100"></polyline> --> <!-- 3. 第三种写法 --> <!-- <polyline points="20, 0, 80, 50, 20, 100"></polyline> --> </svg>
6. 绘制多边形(polygon)
- polyline元素的基本属性
- points:点集数列
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <polygon points="20 0, 80 50, 20 100" fill="transparent" stroke="red"></polygon> </svg>
7. 绘制路径(path)
- path元素的基本属性
- d:一个点集数列,必须以M命令开头
- d属性支持的命令
- M/m: Move To
- L/l: Line To
- Z/z: Close Path
- H/h: horizontal
- V/v: vertical
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <path d="M 20 0,L 80 50,l 20 100 Z" fill="transparent" stroke="red"></path> </svg>
三、绘制文本和图片
1. 绘制文本(text)
- text元素的基本属性
- x和y属性决定了文本在用户坐标系中显示的位置
- text-anchor文本流方向属性,可以有start、middle、end和inherit值,默认值start
- dominant-baseline基线对齐属性,有auto、middle或hanging值,默认值auto
- tspan元素
- 用来标记大块文本的子部分,它必须是一个text元素或别的tspan元素的子元素
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <text x="100" y="100" text-anchor="middle" dominant-baseline="middle" font-size="50" fill="red">Ay</text> </svg>
2. 绘制图片(image)
- image元素的基本属性
- x, y
- width,height
- href
- 基本使用
<!-- svg 2.0版本的语法 --> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <image x="10" y="10" href="xxxxxx" width="100" height="100" > </image> </svg> <!-- 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="10" y="10" xlink:href="xxxxxx" width="100" height="100" > </image> </svg>
四、SVG图形对象组合和引用
1. 元素的组合(g)
- 什么是元素的组合
- g元素是用来组合元素的容器。
- 添加到g元素上的变换会应用到其所有的子元素上。
- 添加到g元素的属性大部分会被所有的子元素继承。
- g元素也可以用来定义复杂的对象,之后通过use元素来引用他们。
- g元素的属性(该元素只包括全局属性)
- 核心属性:id
- 样式属性:class、style
- CSS属性:cursor、display、fill、stroke……
- 事件属性:onchange、onclick、ondrag……
- 动画属性:transform
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <g fill="transparent" stroke="red"> <circle cx="50" cy="50" r="25"></circle> <circle cx="80" cy="50" r="25"></circle> <circle cx="110" cy="50" r="25"></circle> <circle cx="140" cy="50" r="25"></circle> </g> </svg>
2. 图形元素的复用(defs)
- defs元素,定义可复用元素
- SVG可以把可复用的元素定义在defs元素里面,然后通过use元素来引用和显示
- defs元素定义的图形元素不会直接显示
- defs元素没有专有属性,使用时也不需要添加任何属性
3. 引用元素(use)
- use元素从SVG文档中获取节点,并将获取到的节点复制到指定的地方。
- use元素的属性
- href
- x/y
- width/height
- 基本使用
<svg style="display: none" width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <defs> <!-- 样式 --> <style> rect { fill: green; } </style> <!-- 定义了一个矩形 --> <rect id="rectangle" x="0" y="0" width="100" height="50" fill="red"></rect> </defs> <!-- 图形的复用 --> <use x="100" y="100" href="#rectangle"></use> </svg> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <!-- 图形的复用 --> <use href="#rectangle"></use> </svg>
4. 图形元素复用(symbol)
- symbol和defs元素类似,也是用于定义可复用元素,然后通过use元素来引用显示。
- symbol元素的属性
- viewBox:定义当前symbol的视图框
- x/y
- width/height
- symbol和defs的区别
- defs元素没有专有属性,而symbol元素提供了更多的属性。
- symbol元素有自己的用户坐标系,可以用于制作SVG精灵图。
- symbol元素定义的图形增加了结构和语义性,提高文档的可访问性。
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <!-- ICON previous --> <symbol id="previous" viewBox="0 0 100 100"> <path d="M 80 0,L 20 50,L 80 100 Z"></path> </symbol> <!-- 复用 --> <!-- <use href="#previous" width="100" hight="100"></use> --> </svg>
五、样式和属性
1. 填充和描边
- SVG元素上色的方案
- 直接使用元素的属性
- 直接编写CSS样式
- 填充属性(fill)
- fill = "color"
- fill-opacity = "number"
- 描边属性(stroke)
- stroke = "color"
- stroke-opacity = "number"
- stroke-width = "number"
- stroke-linecap = "butt|square|round"
- stroke-linejoin = "miter|round|bevel"
- stroke-dasharray = "number [, number, ……]"
- stroke-dashoffset = "number"
- CSS样式
- 内联(行内)CSS样式,写在元素的style属性上
- 内嵌(内部)CSS样式,写在defs中的style标签中
- 内嵌(内部)CSS样式,写在head的style标签中
- 外部CSS样式,写在.css文件中
2. 渐变
- 线性渐变的使用步骤
- 在SVG文件的defs元素内部,创建一个linearGradient节点,并添加id属性;
- 在linearGradient内编写几个stop节点;
- 给stop节点指定位置offset属性和颜色stop-color属性,用来指定渐变在特定的位置上应用什么颜色;
- 也可以通过stop-opacity来设置某个位置的半透明度。
- 在一个元素的fill属性或stroke属性中通过ID来引用linearGradient节点。url(#ID)。
- 控制渐变方向。也可以通过gradientTransform属性设置渐变形变。
- 基本使用
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <!-- 定义可以复用的元素:样式、渐变、图形、滤镜…… --> <defs> <!-- 默认的渐变色 --> <linearGradient id="gradient1"> <stop offset="0%" stop-color="red"></stop> <stop offset="50%" stop-color="green"></stop> <stop offset="100%" stop-color="blue"></stop> </linearGradient> <!-- 这个是制定渐变的方向 --> <linearGradient id="gradient2" x1="0" y1="0" x2="0" y2="1"> <stop offset="0%" stop-color="red"></stop> <stop offset="50%" stop-color="green"></stop> <stop offset="100%" stop-color="blue"></stop> </linearGradient> <!-- 通过形变渐变色 --> <linearGradient id="gradient3" gradientTransform="rotate(10)"> <stop offset="0%" stop-color="red"></stop> <stop offset="50%" stop-color="green"></stop> <stop offset="100%" stop-color="blue"></stop> </linearGradient> </defs> <rect x="10" y="10" width="100" height="50" fill="url(#gradient1)"></rect> <rect x="10" y="70" width="100" height="50" fill="url(#gradient2)"></rect> <rect x="10" y="130" width="100" height="50" fill="url(#gradient3)"></rect> </svg>
3. 毛玻璃效果
- backdrop-filter
- 给指定元素后面区域增加模糊效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } .box { position: relative; width: 200px; height: 200px; } .bg-cover { position: absolute; left: 0; top: 0; width: 100%; height: 100%; /* 做毛玻璃效果 高斯模糊 */ background-color: transparent; backdrop-filter: blur(5px); } </style> </head> <body> <div class="box"> <img src="xxxxxx" alt=""> <div class="bg-cover"></div> </div> </body> </html>
- filter
- 应用于指定元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } .box { position: relative; width: 200px; height: 200px; overflow: hidden; } img { /* 毛玻璃效果 */ filter: blur(5px); } </style> </head> <body> <div class="box"> <img src="xxxxxx" alt=""> </div> </body> </html>
- SVG毛玻璃效果
- filter:元素作为滤镜操作的容器,该元素定义的滤镜效果需要在SVG元素上的filter属性引用。
- feGaussianBlur:该滤镜专门对输入图像进行高斯模糊。
- feOffset:该滤镜可以对输入图像指定它的偏移量。
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <defs> <!-- 高斯模糊的效果 --> <filter id="blurFilter"> <feGaussianBlur stdDeviation="5"></feGaussianBlur> </filter> </defs> <image href="xxxxxx" filter="url(#blurFilter)"></image> </svg>
六、SVG形变
1. 平移(translate)
- translate(x, y)
2. 旋转(rotate)
- rotate(deg, cx, cy)
3. 缩放(scale)
- scale(x, y)
7、SVG动画
1. 路径描边
- stroke-dasharray
- stroke-dashoffset
- CSS3 animation
2. SMIL动画
- 认识SMIL动画
- SMIL是W3C推荐的可扩展标记语言,用于描述多媒体演示。
- SMIL标记是用XML编写的,与HTML有相似之处。
- SMIL允许开发多媒体项目,例如:文本、图像、视频、音频等。
- SMIL 定义了时间、布局、动画、视觉转换和媒体嵌入等标记。
- SVG动画元素是基于SMIL实现。
- SVG中SMIL动画的基本使用
- set:可以在指定的时间内设置属性的值。
- attributeName:指示将在动画期间更改的目标元素的属性的名称。
- to:定义在特定时间设置目标属性的值。
- begin:定义何时开始动画或何时丢弃元素。
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="100" height="50" fill="red"> <set attributeName="x" to="200" begin="1s" ></set> </rect> </svg>
- animate
- attributeName
- values/from-to
- begin
- dur:动画的持续时间,该值必须,并要求大于0.
- fill:定义动画的最终状态。freeze(保持最后一个动画帧的状态)|remove(保持第一个动画帧的状态)。
- repeatCount:指示动画将发生的次数。number|indefinite。
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="100" height="50" fill="red"> <animate attributeName="x" form="0" to="200" dur="3s" begin="2s" fill="freeze" ></animate> </rect> </svg> <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="100" height="50" fill="green"> <animate attributeName="fill" values="green; red" dur="3s" repeatCount="indefinite" ></animate> </rect> </svg>
- animateTransform
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect x="0" y="0" width="100" height="50"fill="red"> <animateTransform attributeName="transform" type="translate" from="0, 0" to="100, 0" dur="2s" begin="1s" repeatCount="indefinite" ></animateTransform> </rect> </svg> <svg width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect x="0" y="0" width="100" height="50"fill="red"> <animateTransform attributeName="transform" type="translate" values="0 0; 200 0" dur="2s" begin="1s" repeatCount="indefinite" ></animateTransform> </rect> </svg>
- animationMotion
- path:定义运动的路径,值和path元素的d属性一样,也可用href引用一个path。
- rotate:动画元素自动跟随路径旋转,使元素动画方向和路径方向相同。
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <!-- 图形 --> <path id="linePath" d="M 0 100, L 100 30, L 200 100, L 300 30" fill="transparent" stroke="red"></path> <rect id="rectangle" x="-10" y="-5" width="20" height="10" rx="4" ry="5" fill="red"> </rect> <!-- 动画 --> <animateMotion href="#rectangle" dur="5s" rotate="auto" fill="freeze" > <mpath href="#linePath"></mpath> </animateMotion> </svg>
- set:可以在指定的时间内设置属性的值。
3. 第三方动画库
- Snap给SVG中的标签添加动画