文章目录
- 前端的可视化
- 解决方案
- 2D动画-transfrom
- 坐标系
- 3D动画
- 3d旋转-rotateZ,rotateX,rotateY
- 3D透视-perspective
- 3d位移
- 3d缩放
- 3d空间-transfrom-style
- 3d-背面可见性
- 浏览器渲染流程
- css动画性能优化
- canvas
- 应用场景
- 优点:
- 缺点:
- 基本使用
- canvas的坐标系统
- 绘制矩形
- 路径
- 色彩 Colors
- 透明度 Transparent
- 线型line Styles
- 绘制文本
- 绘制图片
- Canvas绘画状态 -保存和恢复
- 变形Transfrom
- Canvas动画
- 数据可视化SVG
- 优点
- 缺点
- 场景
- 基本使用
- 步骤
- XML和DTD声明
- SVG的使用方式
- svg的网格系统
- SVG绘制基本的图形
- 绘制路径(path)
- 绘制图片
- 绘制文本
- 元素的组合(ge)
- 图形元素的复用(defs)
- 填充和描边
- 线性渐变
- 使用步骤
- SVG滤镜
- SVG毛玻璃效果
- 形变-transfrom
- stroke描边动画
- SMIL语言
- SMIL动画元素
- Set元素
- Animate元素
- animateTransfrom元素
- animateMotion元素
- animateTransfrom元素
- animateMotion元素
前端的可视化
解决方案
- 底层图形引擎:Skia,OpenGL
- W3C提供:css3,Canvas,SVG,WebGL
- 第三方的可视库:ZRender,Echarts,AntV,Highcharts,D3.js,Thress.js和百度地图,高德地图
2D动画-transfrom
- CSS3 transfrom属性允许你旋转,倾斜平移,给定元素。
- 常见的函数:
- 平移:translate
- scale缩放
- 旋转:rotate
- 倾斜:skew(deg,deg)
坐标系
- css3 transfrom属性允许你在二维或三维空间中直观的变换元素
- transfrom属性只会转换元素的坐标系,使元素在空间中转换。
- 用transfrom属性变换的元素会受到transfrom-origin属性值影响,该属性用于指定形变的原点
- 元素的坐标系
- css中每一个元素都有一个坐标系,其原点位于元素的左上角,左上角这被称为初始坐标系。
- 用transfrom时,坐标系的原点默认会移动到元素的中心
- 因为transfrom-origin属性的默认值为50%,50%时,则该原点会变换到元素的原点
- 用transfrom属性旋转或倾斜元素,会变换或倾斜元素的坐标系,并且该元素所有后续变换都将基于新坐标的变换
- 因此transfrom属性中变换函数的顺序会很重要,不同的顺序会导致不同的变化效果。
3D动画
css3 transfrom属性不但允许你进行2D旋转缩放或者平移,还支持3D变换元素
- 常见的函数transfrom function
- 平移:translate3d(x,y,z)
- 缩放:scale3d:(x,y,z)
- 旋转:rotate3d(x,yx,z,a)
- 通过这些函数,我们就可以改变某个元素的3D形变
- 3D形变函数会创建一个合成层来启用硬件加速,比如:translate3d,translateZ、等等
3d旋转-rotateZ,rotateX,rotateY
- 旋转
- 该css函数定义一个变换,它将函数围绕固定轴,旋转量指定的角度确定,为正,旋转将为顺时针,为负,则为逆时针旋转
- 值个数
- 只有一个值,表示旋转的角度(deg
- 值类型:
- deg:angle类型,表示旋转角度
- 正数为顺时针
3D透视-perspective
- 透视:perspective
- 定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果。
- 值个数
- 只有一个值,表示观测者距离z=0的距离和none
- 必须中的一个
- 透视的俩种使用方式
- 在父元素上定义css透视属性
- 如果他是子元素或单元素子元素,可以使用函数perspective()
3d位移
主要遵循远小近大的效果,
3d缩放
- 缩放:scale3d:(x,y,z)
- 函数指定了一个沿着xyz轴调整元素缩放比例的因子
- 值个数
- 一个值时,设置对应轴上的缩放
- 值类型:
- 数字:1,2,等等
- 不支持百分比
3d空间-transfrom-style
-
变换式:transfrom-style
- 该css属性用于设置元素的子元素是定位在3d空间中还是平展在元素的2d平面上
- 在3d空间中同样是可以使用透视效果的
-
值类型:
- flat:指示元素的子元素位于元素本身的平面内
- preserve-3d:指示元素的子元素位于3d-空间中。
-
案例制作正方体:
-
<!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> * { margin: 0; padding: 0; } body { padding: 200px; } .box { width: 200px; height: 200px; /* margin:0 auto; */ transform-style: preserve-3d; /* perspective: 200px; */ /* background-color: pink; */ /* transform-origin: 0 0; */ transform: rotateX(-33.5deg) rotateY(45deg); } .item { position: absolute; left: 0; top: 0; width: 100%; height: 100%; } .up { background-color: rgba(255, 0, 0,0.4); transform: rotateX(90deg) translateZ(100px) ; } .down { background-color: rgba(46, 139, 87,0.4); transform: rotateX(-90deg) translateZ(100px); } .face { background-color: rgba(70, 130, 180,.4); transform: translateZ(100px); } .back { background-color: rgba(210, 180, 140,.4); transform: translateZ(-100px); } .left { background-color: rgba(255, 255, 0,.4); transform: rotateY(90deg) translateZ(-100px); } .right { background-color: rgba(238, 130, 238,.4); transform: rotateY(90deg) translateZ(100px); } </style> </head> <body> <div class="box"> <div class="item face"></div> <div class="item back"></div> <div class="item left"></div> <div class="item right"></div> <div class="item up"></div> <div class="item down"></div> </div> </body> </html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RhI8gypx-1691122921215)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230729213639047.png)]
3d-背面可见性
-
背面可见性:backface-visibility
- 该css属性backface-visibility指定某个元素朝向观察者时是否可见
-
值类型:
- visible:背面朝向用户时可见
- hidden:背面朝向用户时不可见。
-
案例-制作webpack logo
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6sBaxcqy-1691122921217)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230730115837300.png)]
浏览器渲染流程
- 1、解析HTML。构建DOM Tree
- 2、对css文件进行解析,解析出对应的规则树
- 3、DOM Tree+CSSOM生成Render Tree
- 4、布局(Layout):计算每个节点的宽度、高度和位置信息
- 页面元素位置,大小变化,往往会导致其他节点联动
- 需要重新计算布局,这个过程称为回流(Reflow)
- 5、绘制:将可见1元素绘制在屏幕中。
- 默认标准是在同一层上绘制,一些特殊属性会创建新的层绘制,这些层称为渲染层
- 一些不影响布局的css修改也会导致改渲染层重绘(Repaint),回流必然会导致重绘
- 6、Composite合成层:一些特殊属性会创建一个新的合成层(CompositingLayer)、并且可以利用GPU来加速绘制,这是浏览器的一种优化手段。合成层确实可以提供属性,但是他以消耗内存为代价,因此不能滥用作为web性能来优化策略和过渡使用
css动画性能优化
-
创建一个新的渲染层(减少回流)
- 有明确的定位属性(relative,fixed,sticky,absolute)
- 透明度:option(小于1)
- 有CSS transfrom属性(不为none
- 当前有对于opacity、transfrom、fliter、backdrop-filter应用动画
- backface-visibility:属性为hidden
-
创建合成层。合成层会开始GPU加速页面渲染、但不能滥用
- 有对opacity、transfrom、filter、backdropfilter应用了animation或transltion(需要是active的animation或者transition)
- 有3Dtranfrom函数:比如translate3D,translateZ,scale3d,rotate3d…
- will-change设置为opacity、transfrom、top、left、bottom、right、比如will-change:opacity、transfrom;
- 其中top、left等需要设置明确的定位属性、如relative等
canvas
Canvas是最初由Apple于2004年引入。并被W3C提议为下一代的标准元素
- Canvas提供了很多的JavaScript的绘图API,(如:绘制路径,图,园,文本和图形)集合元素可以绘制各种2D图形
- Canvas API主要于绘制2D图形当然也可以使用Canvas提供了WebGL API来绘制3D图形。
应用场景
可以用于动画,游戏动画,数据可视化,图片编辑以及实时视频处理等方面
优点:
- Canvas提供的功能更加原始,适合像素级别处理,动态渲染和量大数据的绘制,如:图片编辑、热力图、炫光尾迹特效等
- Canvas非常适合图形密集型的游戏开发、适合频繁大量的图像对象。
- Canvas能够以.png,或.jpg格式保存图形,适合图片进行像素级别的处理
缺点:
-
在移动端如果Canvas使用数量过多,会使内存占用超出了手机承受范围,可能会导致浏览器崩溃
-
Canvas绘图只能通过JavaScript脚本操作。
-
Canvas是由一个个像素点构成的图像,放大会使图形变得颗粒状和像素化(导致图形模糊)。
注意事项
-
和元素很相像,不同的就是他没有src和alt属性。
-
标签只有倆个属性-width和height,没宽高时,Canvas会初始化宽为300px,高位150px
-
改元素必须要结束标签。如果结束标签不存在,则文档其余部分会被认为是替代内容,将不显示出来
基本使用
对一个canvas的基本调用模版:
<!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>
canvas {
background-color: aqua;
}
</style>
</head>
<body>
<canvas id="tutorial" width="300px" height="300px"></canvas>
<script>
window.onload =function() {
let canvasEl = document.querySelector('#tutorial')
// console.log(canvasEl.getContext);
if(!canvasEl.getContext) {
return
}
let ctx =canvasEl.getContext('2d')
// console.log(ctx);
}
</script>
</body>
</html>
canvas的坐标系统
- canvas grid
- 假如、HTML模板中有个宽150px、高150px的canvas元素。canvas元素默认被网格覆盖
- 网格原点位于坐标(0,0)左上角,所有图形都相对于该原点绘制。
- 网格也可以理解为坐标空间,坐标原点位于canvas元素的左上角(被称为初始化坐标系)
- 网格或坐标空间是可以变化的,甚至可以旋转网格和缩放它。-
- 注意:移动、旋转、缩放坐标系后、默认所有变换都将基于新坐标系的变换。
绘制矩形
-
cavas支持俩种方法可以来绘制矩形:矩形方法,和路径方法
- 路径是点列表、由线段连接。这些线段可以具有不同的线段,弯曲或者不弯曲的、连连续或者不连续的、不同的宽度和不同的颜色
- 初了,矩形,其他图形都是通过一条或者多条路径组合而成的。
-
绘制方法:
- fillRect(x,y,width,height):绘制一个填充的矩形
- strokeRect(x,y,width,height):来绘制一个矩形的边框
- clearReact(x,y,width,height):清除指定矩形区域,
-
方法参数:
- 上面方法都包含相同的参数。
- x与y都指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标(不支持undefined)
- width,height设置矩形的尺寸
路径
-
图形的基本元素时路径,路径是点列表,由线段连接而成可以具有很多形状,弯曲或不弯曲的,连续或不连续的,不同的宽度和颜色。
-
路径是可以用很多子路径组成,这些子路径都是在一个列表中,列表中所有子路径(线,弧形)将构成图形。
-
绘制一个路径甚至一个子路径,通常都是闭合的(会调用closePath来闭合)
ctx.beginPath()
ctx.arc(75,75,50,0,Math.PI*2,true) //绘制
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false) //口(顺时针
ctx.moveTo(65,65)
ctx.arc(60,65,5,0,Math.PI*2,true) // 左眼
ctx.moveTo(95,65)
ctx.arc(90,65,5,0,Math.PI*2,true) // 右眼
ctx.stroke()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iA0UWGEK-1691122921218)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230730143157694.png)]
-
使用路径绘图的步骤:
- 首先需要创建路径起点:beginPath
- 然后使用绘图命令去画出路径(arc,lineTo)
- 之后把路径闭合(closePath,不是必须
- 一旦路径生成,就通过描边(stroke)或填充路径区域(fill)来渲染图形
-
所需函数:
- beginPath():新建一条路径,生成之后,图形绘制命令都被指向到新的路径上绘图,不会关联到旧的路径
- closePath():闭合路径之后的图像绘制命令又重新指向到beginpath之前的上下文中。
- stroke():通过线段来绘制图像的描边(针对当前路径图行)。
- fill():通过填充路径的内容区域生成实心的图像(针对当前路径)
-
移动画笔moveTO(x,y)方法
- moveTO方法是不能画出任何东西,但是它也是路径列表的一部分
- moveTo可以想象为在纸上绘图,如:一只钢笔的笔尖从一个点到另一个点的移动过程,可将笔移动到指定的坐标上。
- 当canvas初始化或者能够绘制一些不连续的路径
-
绘制直线lineTo(x,y)方法,绘制一条从当前位置到指定(x,y)位置的直线
- 有倆个参数(x,y)代表坐标系中直线结束的点
- 开始点和之前绘制的路劲有关,之前路径结束点就是接下来的开始点
- 当然开始点也可以用过moveTO(x,y)函数来改变
-
绘制一个三角形
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5JETpayQ-1691122921219)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230730175113050.png)]
window.onload = function() {
let canvasEl =document.querySelector('.canvas')
if(!canvasEl.getContext) return
let ctx =canvasEl.getContext('2d')
ctx.beginPath()
ctx.moveTo(50,0)
ctx.lineTo(100,50)
ctx.lineTo(50,100)
// ctx.stroke()
ctx.fill()
}
-
绘制一个圆弧(arc)、园(circle)
- 使用arc()方法
- arc(x,y,radius,startAngle,endAngle,anticlockwise)有六个参数
- x,y圆心坐标
- radius:圆弧坐标
- startAngle,endAngle:指定开始,和结束的弧度,以x轴为基准,
- anticlockwise:为一个布尔值,是逆时针时,为true,默认为false,顺时针
-
认识弧度
- 弧度,是平面角的单位,1单位弧度长度等于半径时的圆心,而一个完整的弧度就是Math.PI*2,半圆弧度是Math.PI
-
let canvasEl =document.querySelector('.canvas') if(!canvasEl.getContext) return let ctx =canvasEl.getContext('2d') ctx.beginPath() ctx.arc(50,50,25,0,Math.PI*2,false) ctx.stroke()
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u6d3THos-1691122921219)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230730210556074.png)]
-
路径绘制矩形
-
用rect(x,y,width,height)
-
绘制一个左上角的时候,moveTo(x,y)方法自动设置坐标参数(0,0)也就是说,当前笔触自动重置会默认坐标
-
// 绘制矩形 ctx.beginPath() ctx.rect(100,100,100,50) ctx.stroke()
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3g2trdXK-1691122921219)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230730211112308.png)]
-
色彩 Colors
在上面的俩种填充方式中,设置颜色的方法是:
- fillStyle =color:设置图形的填充颜色,需要在fill()函数前调用
- strokeStyle =color:设置图形轮廓的颜色,需在stroke()函数前调用
color颜色
-
color可以是颜色的字符串,支持:关键字,十六进制,rgb,rgba
-
默认情况下,均默认为黑色
注意:
- 一旦设置strokeStyle或者fillStyle的值,那么这个值就会成为新绘制图像的默认值。
- 如果给图形上不同的颜色,你需要重新设置fillStyle或strokeStyle的值
透明度 Transparent
- 用rgba
- globalAlpha属性,取值范围0-1(全局作用的
线型line Styles
调用lineTo()函数绘制的线条,是可以通过一系列属性来设置线的样式。
-
lineWidth=value:设置线条宽度
-
lineCap=type:设置线条末端样式
- butt截断,默认
- round圆形
- square正方型
-
lineJoin=type:设定线条与线条间接合处的样式
- round圆形
- bevel斜角
- miter斜槽规,默认
绘制文本
- canvas提供俩种方法来渲染文本:
- fillText(text,x,y[,maxWidth]
- 在(x,y)位置,填充指定文本
- 绘制的最大宽度(可选
- strokeText(text,x,y[,maxWidth])
- 在(x,y)位置,填充指定文本
- 绘制的最大宽度(可选
- 文本样式
- font=value:当前绘制文本的样式,和CSSfont属性相同的语法。默认字体为10px sans-serif
- textAlign=value :文本对齐选项。可选的值有:start,end,left,right,center默认是start
- textBaseline=value:基线对齐选项,值有:top,hanging,middle,alphabetic,ideographic,bottom
- fillText(text,x,y[,maxWidth]
绘制图片
绘制图片,可以使用drawlmage方法将他渲染到canvas里,drawlmage方法有三种形态
- drawImage(image,x,y)
- 其中image是image或者canvas对象,x,y是其在目标canvas的起始坐标
- drawImage(image,x,y,width,height)
- z这个方法多倆个参数,这个倆个参数主要用来控制当前canvas滑入时的应该缩放大小
- drawImage(image,sx,sy,swidth,sheight,dx,dy,dwidth,dheight)
图片来源:
-
HTMLImageElement:这些图片是由image()函数构造出来的,或者任何的img元素
-
HTMLVideoElement:用一个HTML的video标签元素作为图片源,可以从视频中抓取当前帧作为一个图像
-
HTMLCanvasElement:可以使用另一个Canvas元素作为图片源
Canvas绘画状态 -保存和恢复
- 是当前绘画时所产生的样式和变形的一个快照
- Canvas在绘画状态的可以调用save,restore方法是用来保存和恢复,这倆个方法都没有参数,并且他们是成对存在的。
- Canvas绘画时,会产生相应的绘画状态,其实我们是可以将某些绘画状态存储到zhai中来为以后复用
- 保存和回复Canvas绘画状态
- save():保存画布(canvas)的所有绘画状态
- restore():恢复画布,的所有绘画状态
- canvas绘画状态包括:
当前应用的变形,(移动,旋转和缩放
以及这些属性:strokeStyle,fillStyle,globaAlpha,lineWidth,lineCap,lineJoin,miterLimit,shadowOffsetX,shadowOffsetY,shadowBlur,shadowColor,font,textAlign,textBeaseline
当前的裁切路径(clipiing
let ctx = canvasEl.getContext('2d')
ctx.fillStyle ='red'
ctx.fillRect(10,10,30,15)
ctx.save()
ctx.fillStyle ='green'
ctx.fillRect(50,10,30,15)
ctx.save()
ctx.fillStyle ='blue'
ctx.fillRect(90,10,30,15)
ctx.save()
ctx.restore()
// ctx.fillStyle ='red'
ctx.fillRect(10,40,30,80)
ctx.restore()
// ctx.fillStyle ='green'
ctx.fillRect(50,40,30,80)
ctx.restore()
// ctx.fillStyle ='blue'
ctx.fillRect(90,40,30,80)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IL5xqKlA-1691122921220)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230731124304109.png)]
变形Transfrom
和css的变形基本一致,可以将坐标原点移动到另一点,形变可以对网格进行旋转和缩放
方法:
- translate(x,y):用来移动Canvas和它的原点到一个不同的位置。
- x是左右偏移量,y是上下偏移量无需单位
- rotate(Angle):用于以原点为中心旋转Canvas,既沿着Z轴旋转
- Angle是旋转 的弧度,顺时针方向,以弧度为单位
- scale(x,y):用来增减图形在Canvas中像素的数目,对图形进行缩小和放大
- x为水平缩放因子,y为垂直缩放因子,
注意:
- 在做变形之前,先调用save方法保存状态是一个很好的习惯。
- 大多数情况下,调用restore方法比手动恢复原先的状态要简单的多
- 如果一个循环中做位移,但没有保存和恢复Canvas状态,很可能最后会发现有些东西不见了,因为它很可能已经超出Canvas的画布以外了
ctx.save() //保存当前状态
ctx.translate(100,100)
ctx.fillRect(0,0,100,50)
ctx.restore()//恢复刚刚保存的状态
ctx.save()
ctx.translate(100,100)
ctx.fillStyle='red'
ctx.fillRect(0,0,50,25)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-offxBxOJ-1691122921220)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230731170942143.png)]
合理的使用,存储和恢复状态,来改变坐标系统
Canvas动画
Canvas绘图都是通过JavaScript去操控的,如果实现一些交互性动画是非常容易的,那么Canvas是如何做动画的?
- Canvas可能最大的限制就是图像一旦绘制出来,他就一直保持下去了
- 为了实现动画,我们需要执行一些重绘的方法,然后在Canvas中有三种方法实现
-
setInterval
-
setTimeout
-
requestAnimationFrame
- 告诉浏览器-你希望执行一个动画,并且要求浏览器在下次重绘之前调用该函数来更新动画
- 该方法需要传入一个回调函数作为参数,该回调函数会再浏览器下一次重绘之前执行
- 若浏览器下次重绘之前继续更新下一帧动画,那么在回调函数自身必须再次回调requestAnimationFrame()
- 通常一秒调用60次
步骤
- 1、用clearReact方法清空Canvas,除非接下来绘制的内容完全充满Canvas,否则需要清空所有。
- 2、保存Canvas状态,如果家里Canvas的状态,邮箱在每一帧都是原始坐标状态 =需要先保存Canvas的状态,然后回到到原始状态
- 3、绘制动画图形,既绘制动画的一帧
案例制作秒针:
1、用clearRect()方法,先清空画布
2、保存Canvas状态
3、修改Canvas
4、绘制秒针图形
5、恢复Canvas状态,准备重绘下一帧
window.onload = function () {
let canvasEl = document.querySelector('#tutorial')
// console.log(canvasEl.getContext);
if (!canvasEl.getContext) {
return
}
let ctx = canvasEl.getContext('2d')
// console.log(ctx);
draw()
function draw() {
// 开始绘画
const s = Math.PI * 2 / 60 //一秒的度数
let time =0
setInterval(() => {
ctx.clearRect(0, 0, 300, 300);
ctx.save()
ctx.translate(150, 150)
ctx.rotate(s*time)
lineWidth = 4
ctx.lineCap = 'round'
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(0, -80)
ctx.stroke()
time++
if(time===60) time=0
ctx.restore()
console.log(time);
}, 1000);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1Gerbtt-1691122921221)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230731175523000.png)]
注意:
-
setInterval定时器不是非常精准的,因为setTimeout的回调函数放到的是宏任务中等待执行的。
-
如果微任务中一直未处理完成的任务,那么setTimeout的回调函数可能不会在指定时间内触发回调
-
更平稳精准的定时器:requestAnimationFrame
做的Canvas动画案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBjF4JO0-1691122921221)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230801120311003.png)]
数据可视化SVG
SVG全称为可缩放矢量图形。(Scalable Vector Graphics)
SVG是一种基于XML格式的矢量图,主要用于定义二维图形,支持交互和动画
SVG规范是万维网联盟1998开发的标准
SVG图形可在不损失质量的情况下按比例缩放,并支持压缩
基于XML的SVG可轻松的使用文本编辑器或矢量图形编辑器,并可以直接在浏览器显示
官网:W3C
优点
-
扩展好:矢量图形在浏览器中放大或缩小不会失真,可被许多设备和浏览器中使用,而光栅图像(PNG,JPG)放大和缩小会失真
-
-灵活:SVG是W3C开发的标准,可结合其他语言和技术一起使用,包括CSS,JavaScript,HTML,SMIL。SVG图形可以直接使用JS和CSS进行操作,非常灵活方便
-
轻量,SVG图形的尺寸非常小,根据图形的不同,PNG图形质量可能是SVG图形的50倍
-
可以动画:SVG可以使用JS,CSS,HTML进行动画处理,对web开发人员非常友好
-
可打印:SVG图形可以在任何分辨率下进行打印,而不丢失图形质量
-
利于SEO:SVG图形被搜索引擎索引,因此,SVG图形非常适合SEO目的
-
可压缩:与其他图片格式一样,SVG文件支持压缩。
缺点
- 不适合和高清图片制作
- SVG格式非常适合用于徽标和图标等2D图形,但不适合用于高清图片,不适合进行像素级别操作。
- SVG的图像无法显示与标准图像格式一样多的细节,因为他们是使用点和路径而不是像素来渲染的
- SVG图像变得非常复杂的时候,加载会变得很慢
- 不完全扩平台
场景
-
svg非常适合显示适量徽标,图标和其他几何设计。
-
SVG适合应用在需适配多种尺寸的屏幕上展示,因为SVG扩展性更好
-
用于做一些简单的动画
-
SVG非常适合制作图表(条形图,折线图,饼图,散点图,以及大屏可视化的开发
基本使用
四种方式:
- 在一个单独的SVG文件中绘制,SVG文件可直接在浏览器或嵌入到HTML中使用
- 直接在HTML文件中使用svg元素来绘制
- 直接使用JavaScript代码来生成svgshliangtu
- 使用AI矢量绘图工具来绘制矢量图,并导出svg文件
步骤
- 新建一个svg文件,在文件第一行编写XML文件声明
- 编写一个svg元素,并给元素添加如下属性
- width,height指视口的宽和高,默认px单位
- xmlns:给svg元素绑定一个命名空间,意味着svg标签和它子元素都属于这个命名空间之下
- 在svg元素中添加图形元素。
- 在浏览器中直接预览或嵌入到HTML中进行浏览
XML和DTD声明
由于svg是一个XML文件格式,在编写XML文件时,通常是推荐编写xml声明,因为XML1.0中。声明是可选的,推荐写但不是强制性的,但在XML1.1中声明是强制性的,如果没有生命,则自动暗示该文档是XML文档,所以这里建议编写svg文件的时候也编写一个XML声明
- svg的XML声明格式:<?xml version="1.0" encoding='UTF-8' standalone ="no" ?>
- version 指定版本
- encoding:指定XML文档编码(可选,默认utf-8)
- standalone:指定当前XML文档是否依赖于外部标记声明,
- 默认为no,代表依赖外部标记声明
- yes:代表依赖内部默认的标记声明
svg的文档类型声明、让解析器验证XML文件是否符合该规范与HTML5文件的DTD声明类型类似
- xml中内部DTD声明(可选
- xml中内部DTD声明(可选
SVG的使用方式
- 1、在html中,直接img标签进行调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pgie058n-1691122921221)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230801162834391.png)]
-
2、在css作为背景图引入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fcN4pEKp-1691122921222)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230801162913090.png)]
-
3、在HTML直接创捷SVG标签,进行编写使用
svg的网格系统
SVG使用的坐标系统(网格系统)和Canvas的差不多,坐标是以左上角为(0,0)坐标原点,坐标原点以像素为单位,x轴为正方向,y轴正方向向下
SVG Grid 坐标系
- svg元素默认宽高为300px,150px。 svg元素默认被网格所覆盖
- 通常来说网络中的一个单元相当于svg的一个像素
- 基本上在svg文档中的一个像素对应输出设备上的一个像素,除非缩放
- svg元素和其他元素也一样,有一个坐标空间,其原点位于元素的左上角,别成为视口坐标系
- svg的transfrom属性可以用来移动、旋转、缩放svg的某个元素,如svg中某个元素用了变形,改元素内部会建立一个新的坐标系,该元素默认后续所有变化都是基于新创建的坐标系统
视口-viewprot
-
视口坐标系
- 视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0,0),x轴正向向右,y轴正向向下。
- 初始视口坐标系中的一个单位等于视口中的一个像素,该坐标系类似于HTML元素的坐标系
-
用户坐标系
-
用户坐标系建立在svg视口上的坐标系,该坐标系最初于视口坐标系相同,他的原点位于视口的左上角
-
使用viewBox属性,可以修改初始用户坐标系,使其不再与视口坐标系相同
-
-
为什么要倆个坐标系?
- 因为svg是矢量图,支持任意缩放,在用户坐标系统绘制的图像,最终会参考视口坐标进行等比例缩放。
视图框-viewBox**
viewprot是svg画布的大小,而viewBox是用来定义用户坐标系中的位置和尺寸(该区域通常会被缩放来填充shikou
viewBox也可理解为是用来指定用户坐标系大小,因为svg图形都是绘制到该区域中。用户坐标系可以比视口坐标系更小或更大、也可以在视口内完全或部分可见
一旦创建视口坐标系(svg使用width和height)浏览器就会创建一个与其相同的默认用户坐标系
使用viewBox属性来指定用户坐标系的大小
- 如果用户坐标系和视口坐标系具有相同的高宽比,他将viewBox区域拉伸以填充视口区域
- 如果用户坐标系和视口坐标系没有相同的宽高比,可以preserveAspectRatio属性来指定整个用户坐标系统是否在视口内可见
viewBox语法:
viewBox=,比如:viewBox=‘0 0 100 100’
用户坐标系和视口坐标系理解
- 两者宽高比相同:
- 在用户坐标系上作图,做完好,会再视口坐标系上等比缩放
- 两者宽高比不同:
- 视口框不会拉伸以覆盖整个视图框,而是先以靠最大的宽和高来进行缩放,然后小的宽和高不会拉伸,但会被居中
- 如果不想保存宽高比,则可以添加preserveAspectRatio属性
SVG绘制基本的图形
svg支持的基本图形有:矩形,圆形,椭圆,线条,折线,多边形,路径
-
绘制矩形:
元素来绘制,共有6个基本属性来控制塔在屏幕上的位置和形状 -
x:矩形在x轴的位置
-
y:矩形在y轴的位置
-
width:矩形的宽
-
height:矩形的宽
-
rx:圆角的x轴方位的半径
-
ry:圆角的Y轴方位的半径
-
-
绘制圆形(cirle)和椭圆:(ellipse)
圆形:<circle
- r:园的半径
- cx:圆心的x轴位置
- cy:圆心的Y轴位置
椭圆:
- cx:椭圆中心的X轴位置
- cy:椭圆中心的Y轴位置
- rx:椭圆的x轴半径
- rx:椭圆的y轴半径
-
绘制直线(line:
-
元素是绘制直线,它取倆个点的位置作为属性,指定这条线的起点和终点位置 - 需要描边才可以展示,不支持填充和Canvas线条一样
- line元素有四个基本属性来设置线条
- x1:起点的X轴位置
- x2:终点的x轴位置
- y1:起点的Y轴位置
- y2:终点的Y轴位置
-
-
-
绘制折线(polyline),与多边形polygon:
- polyline与ploygon元素是一组连接在一起的直线,因为它可以有很多的点,折线的所有点位置都放在一个points属性
- 默认会填充黑色
- points:点集数列.每个数字用空白,或逗号隔开
- 每个点必须包含俩个数字,一个x坐标,一个y坐标
-
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZnzubJC-1691122921222)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230802114617501.png)]
-
- points:点集数列.每个数字用空白,或逗号隔开
绘制路径(path)
path元素可能svg中最常见的形状,可以使用path元素绘制矩形(直角矩形或圆角矩形)、圆形、椭圆,等等
- 默认填充黑色,默认路径不会闭合
- 《path》元素有一个基本属性用来设置路径点的位置
- d:一个点集数列,以及其他操作指令,必须以M命令开头
-
d属性值支持的命令:
每一个命令都用一个关键字母来表示,比如字母M,表示Move To命令,当解析器读到这个命令他就知道是打算移动到某个点。每一个命令都有俩种表市方式,一种大写字母、表示采用绝对定位、另一种小写字母、表示采用相对定位
属性d采用用户坐标系统
直线命令:
- M/m :Move To
- L/l:line To
- Z/z :Close Path
- H/h :horizontal
- V/v Lvertical
曲线,命令
- C:三次贝塞尔曲线
- S;简写三次贝塞尔曲线
- Q:二次贝塞尔曲线
- T:简写二次贝塞尔曲线
绘制图片
-
在svg中绘制一张图片:
- 在image元素中的herf属性引入图片的URL
-
使用注意
- image元素没设置的x,y值,它们自动被设置为0.
- image元素没设置height,width时,默认为图片大小
- width、height等于0,将不会展现这个图片
- 需在herf属性上引入外部图形,不是src
绘制文本
使用《text》元素是用来在SVG画布中绘制文字用的
- text元素的基本属性:
- x和y属性基本决定了文本在用户坐标系中显示的位置
- text-anchor文本流方向属性,可以有start、middle、end、inherit、
- dominant-baseline基线对齐属性:有auto、middle、或hanging、默认auto
它还提供了一些类似于css的属性,来操作文字的样式
- 其他文本相关元素
-
元素用来标记大块文本的子部分、他必须是一个text元素或tspan元素的子元素。 - x,y属性决定了文本在视口窗口显示的位置
- alignment-baseline基线对齐属性:auto、baseline、middle、hanging、top、bottom、默认auto、
-
元素的组合(ge)
-
元素的结合
-
元素是用来组合元素的容器 - 添加到g元素上的变换会应用到其他所有的子元素上。
- 添加到g元素的属性大部分会被其他所有的子元素继承
- g元素也可以用来定义复杂的对象、之后可以通过
-
-
元素的属性:(只包含全局属性 -
核心属性:id
-
样式属性:calss。style
-
Presentation Attributes(也可说是css属性
-
参考网站:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/presentation
-
事件属性:onchange、onclick、ondblclick…
-
动画属性:
-
<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="130" cy="50" r="25"></circle> </g>
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DUyVSH50-1691122921223)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230802161547102.png)]
-
图形元素的复用(defs)
即把可复用的元素定义在
元素中,然后通过《use》元素来引用出来喝显示 这样可以增加SVG内容的易读性,复用性和利于无障碍开发。
-
defs元素定义可复用样式
- 定义基本图形,组合图形,渐变,滤镜、等等
- 在defs元素中定义的图形元素是不会直接显示的
- 可在视口任意地方用《use》来呈现出来
-
元素没有专有的属性、使用时通常也不需要添加任何属性
-
引入元素:
- use等同于深度克隆DOM节点、克隆use元素所在的位置
- 克隆的节点是不可见的、当给
- 元素属性:
- herf:需要复值元素/片段的url或ID,支持跨SVG引用
- x,y,元素的坐标x、y,默认0
- width、height:元素的宽和高,(在引入的是SVG或Symbol元素的时候才起作用)。默认012
-
Symbol元素
和defs元素类似、也是用于定义可复用的元素,然后通过
该元素默认也是不会显示在界面上
- 主要用来定义一些小图标、如:icon、logo等等
属性:
viewBox:定义当前symbol的视图框
x/y:symbol元素的x,y坐标
width、height:元素的宽和高
两者区别:
元素没有专有属性,而元素提供了更多的属性 元素有自己的用户坐标,用户可以用于制作SVG精灵图
填充和描边
如果要给SVG中的元素进行上色,一般俩种方案:
- 直接使用元素的属性、比如填充fill,描边stroke
- 直接编写css样式,因为svg也是html中的元素、也支持用css的方式来编写样式
第一种:
填充属性:
fill :填充颜色,也可以设置为currentColor,这时颜色继承css样式或者父亲盒子
fill-opacity:设置填充的透明度
描边属性:
stroke:指定元素边框填充颜色
stroke-opacity:控制元素边框填充的颜色的透明度
stroke-width:指定边框的宽度。边框以中心线绘制的
stroke-lineCap :可选:butt |square | round ,来控制边框端点的样式
stroke-linejoin:可选: miter | roud | bevel ,控制俩条线段连接处样式
stroke-dasharry :填:number,number,number…(可在后面填更多数字,来控制虚线的数量) 将虚线类型应用到边框上。
stroke-dashoffset:在指定dasharry模式下路径的偏移量。
- 值为number,可以去±值
第二种:css样式
除了定义元素外,也可以用css来实现填充和描边(css可以卸载defs中,也可写在HTML头部或外部。
- 语法和HTML中使用css一样,不同的是,需要把background-color,border变成fill和stroke
- 不是所有的属性都能用css来设置,上色和填充部分是可以来用css设置
- 比如:stroke,stroke-dasharry等路径命令则不行
- 用css编写的优先级:Element Style >defs style > head style /link css >attribute
线性渐变
渐变分为:线性渐变、径向渐变
且渐变建议写在
标签里面
使用步骤
1、在svg文件的defs元素的内部、创建一个节点。并添加id属性。
2、在内编写几个
节点
- 给stop结点指定位置位置offse属性和颜色stop-color属性、用来指定渐变在特点的位置上应用什么颜色
- offset和stop-opacity来设置这倆个属性值,也可以通过css设定
- 也可通过stop-opacity来设置某个位置的半透明度。
3、在一个元素的fill属性或stroke属性中通过ID来引用节点。
4、控制渐变方向、通过(x1,y1)和(x2,y2)俩个点控制
默认的渐变方式:
<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>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KRe2QyrW-1691122921223)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230803162146427.png)]
设置方向的渐变:
<linearGradient id="gradient2" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPLfup6w-1691122921223)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230803162244981.png)]
这个方向主要是根据两点连线的方向。
SVG滤镜
SVG毛玻璃效果
方案一:
使用css的backdrop-filter或filter属性中的blur()
- backdrop-filter:可以给一个元素后面区域添加模糊效果
- 适用于元素的背后的所有元素、必须是元素或其背景部分为透明
- filter:直接将模糊或颜色偏移等模糊效果应用于指定的元素。
方案二:
- filter:元素作为滤镜操作的容器、该元素定义的滤镜效果需要再SVG元素上的filter属性引用
- x,y,width,height、定义了在画布上应用此滤镜效的矩形区域。x,y默认值为-10%;width。height、默认值为120%
- :该滤镜专门对输入图像进行高斯模糊
- stdDeviation 熟悉指定模糊的程度
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="blurFilter">
<feGaussianBlur stdDeviation="8"></feGaussianBlur>
</filter>
</defs>
<image href="./images/QQ图片20211115122628.jpg" width="100%" filter="url(#blurFilter)"></image>
</svg>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hRiwV63w-1691122921224)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230803164426948.png)]
形变-transfrom
- transfrom属性用来定义元素及其子元素的形变的列表
- 从SVG开始,transfrom它是一个Presentation Attribute、意味它可以用作css属性
- 但是transfrom作为css属性和元素之前的语法会由一些差异。
transfrom属性支持的函数
- translate(x,y)平移 x,y的值都不需要代单位
- rotate(z)/rotate(z,cx,cy)旋转 ,可指定旋转的原点(cx,cy及指定原点),默认左上角
- scale(x,y):缩放 (缩放会修改坐标系,相当于坐标被缩放了)
- skew:倾斜
- matrix(a,b,c,d,e):2*3矩阵
形变会修改坐标系,形变后内部会建立一个新的坐标系、后续的绘图或形变都会参考新的坐标系。
stroke描边动画
stroke是描边属性、
实现步骤:
- 1、先将描边设置为虚线
- 2、接着将描边偏移到不可见处
- 3、通过动画让描边慢慢变为可见、
svg {
background-color: pink;
}
#line1 {
stroke-dashoffset: 100;
animation: lineMove 2s linear forwards ;
}
@keyframes lineMove {
100% {
stroke-dashoffset: 0;
}
}
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<line id="line1" x1="100" y1="70" x2="200" y2="70" stroke="red"
stroke-width="10" stroke-dasharray="100">
</line>
</svg>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8CskjbM0-1691122921224)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230804105208034.png)]
SMIL语言
SMIL是W3C推荐的标记语言,用于描述多媒体演示
- SMIL标记是用XML编写的、与HTML有相识之处
- SMIL允许开发多媒体项目、例如文本、图像、视频、音频。
- SMIL定义了时间、布局、动画、视觉转换、和媒体嵌入、
应用:
- 目前最常用的Web浏览器基本都支持SMIL语言
- SVG动画元素基于SMIL实现的
实现方式:
- 用JS脚本实现
- 用css样式实现
- 使用SMIL实现
SMIL优势:
-
变动一个元素的数字属性
-
变动变形属性
-
变动颜色属性
-
物件的方向=运动路径方向同步
-
支持声明动画
SMIL动画元素
Set元素
set元素是最简单的SVG动画元素、它是在经过特定时间间隔后、将属性设置为某个值、因此图像不是连续动画、而是变了一次属性值。
它支持所有属性类型,包括那些无法合理插值的属性类型、
常用属性:
- attributeName:指示在动画期间更改的目标元素的css属性或属性的名称
- to:定义在特定的时间设置目标属性的值,该值必须与目标属性的要求匹配。值类型:Anything
- begin:定义何时开始动画或何时丢弃元素。默认是0s,支持多种类型的值
Animate元素
animate元素给某个属性创建过渡动画效果、需要将animate元素嵌套到应用动画的元素内
常用属性:
- attributeName:指定动画期间更改目标元素的Property(css属性)或attribute的名称
- 动画属性:
- from:在动画期间将被修改的属性的初始值,没有默认值。
- to:在动画期间将被修改的熟悉的最终值、没有默认值
- values:该属性具有不同的含义,具体取决于使用它的上下文。
动画时间属性:
-
begin:定义时间开始动画或何时丢弃动画,默认0s
-
dur:动画的持续时间、该值必须、并且要求大于0.单位可用时,分秒毫秒
-
fill:定义动画的最终状态、freeze(保存最后一帧的状态)|remove(保存第一个动画帧的状态
-
repeatCount:指示动画将发生的次数: | <indefinite. 没有默认值
<rect x="0" y="0" width="100" height="50" fill="red">
<animate attributeName="x"
values="0;50;200"
dur="2s"
repeatCount="indefinite"></animate>
</rect>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4SyTqpvl-1691122921225)(C:\Users\Dong\AppData\Roaming\Typora\typora-user-images\image-20230804115437776.png)]
animateTransfrom元素
指定目标元素的形变属性、从而允许控制属性的平移旋转缩放倾斜动画
在一个动画元素中、只能用一个《animateTransfrom》元素来创建动画;存在多个时、后面会覆前面的动画
常用属性:
- attributeName:指示将在动画期间更改的目标元素的css属性、或属性的名称
- type:一个指定类型属性、在不同的使用场景下、具有不同的意思。有:translate、rotate、scale、skew
- 动画值属性:from,to,values
- 动画时间属性:begin、dur、fill、repeatCount
animateMotion元素
定义一个元素如何沿着运动路径进行移动
要复用现有路径、建议从(0,0)开始
要复用现有路径,可在元素中使用
元素
常用属性:
- path:定义运动路径、值和path元素的d属性一样、也可用href引用一个path
- rotate:动画元素自动跟随路径旋转、使元素动画方向和路径方向相同、值类型 数字 | auto | auto-resverse ;默认0
- 动画属性:from、to、values、
- 动画时间属性:begin、dur、fill、repeatCount
目标元素的Property(css属性)或attribute的名称
- 动画属性:
- from:在动画期间将被修改的属性的初始值,没有默认值。
- to:在动画期间将被修改的熟悉的最终值、没有默认值
- values:该属性具有不同的含义,具体取决于使用它的上下文。
动画时间属性:
-
begin:定义时间开始动画或何时丢弃动画,默认0s
-
dur:动画的持续时间、该值必须、并且要求大于0.单位可用时,分秒毫秒
-
fill:定义动画的最终状态、freeze(保存最后一帧的状态)|remove(保存第一个动画帧的状态
-
repeatCount:指示动画将发生的次数: | <indefinite. 没有默认值
<rect x="0" y="0" width="100" height="50" fill="red">
<animate attributeName="x"
values="0;50;200"
dur="2s"
repeatCount="indefinite"></animate>
</rect>
[外链图片转存中…(img-4SyTqpvl-1691122921225)]
animateTransfrom元素
指定目标元素的形变属性、从而允许控制属性的平移旋转缩放倾斜动画
在一个动画元素中、只能用一个《animateTransfrom》元素来创建动画;存在多个时、后面会覆前面的动画
常用属性:
- attributeName:指示将在动画期间更改的目标元素的css属性、或属性的名称
- type:一个指定类型属性、在不同的使用场景下、具有不同的意思。有:translate、rotate、scale、skew
- 动画值属性:from,to,values
- 动画时间属性:begin、dur、fill、repeatCount
animateMotion元素
定义一个元素如何沿着运动路径进行移动
要复用现有路径、建议从(0,0)开始
要复用现有路径,可在元素中使用
元素
常用属性:
- path:定义运动路径、值和path元素的d属性一样、也可用href引用一个path
- rotate:动画元素自动跟随路径旋转、使元素动画方向和路径方向相同、值类型 数字 | auto | auto-resverse ;默认0
- 动画属性:from、to、values、
- 动画时间属性:begin、dur、fill、repeatCount