案例+图解带你一文读懂SVG (2.6W+字)
SVG 是 Scalable Vector Graphics 的缩写,意为可缩放矢量图形。于 2003年1月14日 SVG 1.1 被Sun公司(已被Oracle公司收购)、Adobe、苹果公司、IBM 以及柯达共同确立成为W3C推荐标准。
那么SVG究竟是什么呢?
SVG是 Scalable Vector Graphics 的缩写 意为可缩放矢量图形
SVG是一个基于文本的开放网络标准,用来定义用于网络的矢量图形
SVG图像在放大或改变尺寸的情况下其图形质量不会有所损失,因此能够优雅而简洁地渲染不同大小的图形,并和CSS,DOM,JavaScript和SMIL等其他网络标准无缝衔接
SVG 使用 XML 格式定义图形
SVG是万维网联盟的标准与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
相对于其他格式的图像,SVG的优势有很多:
SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
SVG图像中的文本是可选的,同时也是可搜索的,且可以与 JavaScript 技术一起运行
SVG可在图像质量不下降的情况下被放大和缩小
SVG可被非常多的工具读取和修改(比如文本编辑器)
SVG图像不依赖分辨率,可在任何的分辨率下被高质量地打印
SVG文件是纯粹的XML
SVG是开放的标准
SVG复杂度越高渲染速度就会越慢(任何过度使用DOM的应用都不快)
SVG不适合游戏应用,只能结合Canvas来实现
SVG不能动态的修改动画内容
PS: 需要注意的是因为XML和HTML不同,XML是区分大小写的,而SVG是使用XML格式来定义图形,所以在编写SVG的的时候元素和属性必须按标准格式书写。
这里直接放一张 Can I Use[3] 的详细兼容表。
image.png
以上就是SVG的简介,下面将进入SVG的学习。
SVG的语法如下:
复制代码
如上面的语法所示,SVG的绘制其实就是一个SVG标签,然后在标签内绘制你要绘制的内容,比如上面的语法是在SVG标签中绘制了一个圆形(cx、cy为圆的坐标,r为圆的半径)。
代码如下:
SVG - 语法
复制代码
效果如下:
image.png
SVG的属性有哪些?
width、height设置用来设置SVG的宽高。
举个例子看一下:设置SVG的宽高为300 * 300
SVG - 属性
复制代码
效果如下:
注意:在不设置宽高的情况下,默认为300 * 150,当内部元素大于300 * 150时,大于部分会被隐藏。
举个例子看一下:在坐标为(100, 100)的地方绘制一个半径为100的圆
SVG - 属性
复制代码
效果如下:
image.png
viewBox 属性定义了SVG中可以显示的区域。
语法:viewBox="x y w h"
x、y为起始点,w、h为显示区域的宽高。
看字面意思,我觉得你肯定是会理解错的,举个例子看一下:
下面我们将在一个尺寸为300 * 300的SVG中绘制一个坐标为(100, 100)半径为100的圆,同时我们加上viewBox属性为"0 0 100 100"
SVG - 属性
复制代码
效果如下:
image.png
如图SVG里面的圆只显示了一部份,原因是viewBox定义了一个:从(0, 0)点开始,宽高为100 * 100的显示区域。而这个100 * 100的显示区域会放到300 * 300(svg宽高)的SVG中去显示,整体就放大了3倍。
version属性用于指明SVG的版本,也就是指明SVG文档应该遵循的规范。version属性纯粹就是一个说明,对渲染或处理没有任何影响。且目前只有1.0 和 1.1这两个版本。
示例:
复制代码
下面是来自维基百科的一些版本信息:
SVG 1.0于 2001 年 9 月 4 日成为W3C 推荐标准。
SVG 1.1 于 2003 年 1 月 14 日成为 W3C 推荐标准。SVG 1.1 规范是模块化的,以便允许将子集定义为配置文件。除此之外,SVG 1.1 和 SVG 1.0 之间几乎没有区别。
SVG Tiny和SVG Basic(移动 SVG 配置文件)于 2003 年 1 月 14 日成为 W3C 推荐标准。这些被描述为 SVG 1.1 的配置文件。
SVG Tiny 1.2 于 2008 年 12 月 22 日成为 W3C 推荐标准。它最初是作为计划中的 SVG Full 1.2 的配置文件(后来被 SVG 2 放弃),但后来被重构为独立规范。它通常得不到很好的支持。
SVG 1.1 第二版,包括所有勘误表和说明,但在 2011 年 8 月 16 日发布的原始 SVG 1.1 没有新功能。
SVG Tiny 1.2 Portable/Secure,SVG Tiny 1.2 配置文件的更安全子集,于 2020 年 7 月 29 日作为 IETF 草案标准引入。也称为 SVG Tiny P/S。SVG Tiny 1.2 Portable/Secure 是BIMI草案标准的要求。
SVG 2 删除或弃用了 SVG 1.1 的一些特性,并结合了HTML5和Web 开放字体格式的新特性:
例如,SVG 2 删除了几个字体元素,例如glyph和altGlyph(由 WOFF 字体格式替换)。
不推荐使用该xml:space属性以支持 CSS。
添加了HTML5 功能,例如translate和data-*属性。
SVG Tiny 1.2 中的文本处理功能被注释为包含在内,但尚未在文本中正式化。其他一些 1.2 特性是精选的。但 SVG 2 通常不是 SVG tiny 1.2 的超集。
SVG 2 于 2016 年 9 月 15 日进入候选推荐阶段,修订版于 2018 年 8 月 7 日和 2018 年 10 月 4 日发布。最新草案于 2022 年 3 月 21 日发布。
上面我们说过SVG使用XML格式定义图形,SVG文件是纯粹的XML文件。
在XML中,标签和属性属于命名空间,这是为了防止来自不同技术的标签和属性发生冲突。例如在SVG中存在a标签,在HTML中也存在a标签,那么怎么区分这个a标签属于哪一种技术,这就需要使用命名空间了。加入命名空间以后我们就能知道哪一个是svg:a,哪一个又是html:a,这样我们就可以区分出不同的标签和属性。
xmlns用于声明命名空间(namespace),在此声明之下的所有子标签都属于这个空间内。这里看起来是一个url,但实际上仅仅是一个字符串,这样使用只是惯例。因此很多时候都会被称为”namespace url” 而不是”namespace name”。
当我们在SVG中加入xmlns时,因为它定义了默认命名空间,因此不需要前缀,我们直接在SVG标签中写一个a标签,a标签和UA就知道它是SVG的a标签而不是HTML的a标签
xmlns:xlink 表示前缀为xlink的标签和属性,应该由理解该规范的UA 使用xlink规范 来解释。
注解:UA是User Agent的简称。User Agent是Http协议中的一部分,属于头域的组成部分。通俗地讲UA是一种向访问网站提供你所使用的浏览器类型、操作系统、浏览器内核等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版,从而为用户提供更好的体验或者进行信息统计。
示例:
复制代码
基本图形其实就是我们插入到SVG标签中的元素,如上面示例中的圆形(circle)。
下面我们将依次介绍几个基本图形。
circle 标签能在屏幕上绘制一个圆形
语法:
属性:cx、cy为圆的坐标,r为圆的半径
示例:
SVG - 基本图形
复制代码
效果:
image.png
rect标签能在屏幕上绘制一个矩形
语法:
属性:x、y为矩形的起始点坐标,rx、ry为圆角x、y轴方向的半径, width、height为矩形的宽高
示例:
SVG - 基本图形
复制代码
效果:
image.png
ellipse标签比circle标签功能更强大,ellipse标签也可以实现圆形的绘制,并且还可以分别缩放圆形的长轴半径和短轴半径,从而达到椭圆的效果。
语法:
属性:cx、cy为椭圆的坐标,rx为椭圆的x轴半径、ry为椭圆的y轴半径
示例:
SVG - 基本图形
复制代码
效果:
image.png
line标签可以根据两点的坐标绘制一条直线
语法:
属性:x1、y1为起点的坐标,x2、y2为终点的坐标
示例:
SVG - 基本图形
复制代码
效果:
image.png
polyline标签可以把很多个点链接在一起成为一条折线。
语法:
属性:points为点集数列,其中每个点都必须包含2个数字,一个是x坐标,一个是y坐标。
示例:
SVG - 基本图形
复制代码
效果:
image.png
polygon标签和polyline标签类似,都是由很多个点链接在一起的。但不同的是polygon路径中的最后一个点和第一个点是默认闭合的。
语法:
属性:points为点集数列,其中每个点都必须包含2个数字,一个是x坐标,一个是y坐标。
示例:和折线(polyline)同样的数据
SVG - 基本图形
复制代码
效果:
image.png
path标签是所有图形中最复杂的,但他也是最强大的。在SVG中最常用的图形就是path标签,他可以绘制圆形、椭圆、矩形、线条、折线、多边形、贝塞尔曲线等。
语法:
属性:d为一个点集数列以及其它绘制路径的信息。
示例:
SVG - 基本图形
复制代码
效果:
image.png
看着上面的例子是不是很懵X?感觉就是一个简单的正方形但是怎么看都看不懂,什么M、H、V和L,根本不知道是啥。
下面我们着重说一下路径(path),让我们从此能看懂SVG。
上面对路径(path)的举例其实已经是一个很简单的例子了,但是呢我们还是发现我们看不懂,下面我们就看看路径(path)里的这个属性d究竟是什么玩意。
path标签的图形形状是通过属性d来定义的,属性d的值是以:命令 + 参数 的形式进行组合的,命令又是通过关键字来表示的。
那么究竟有哪些命令呢?我总结了一下概括为以下10个命令:
M = Move to
L = Line to
H = Horizontal Line to
V = Vertical Line to
Q = Quadratic Bezier Curve to
T = Smooth Quadratic Bezier Curve to
C = Curve to
S = Smooth Curve to
A = Elliptical Arc
Z = close path
下面我们将命令分为直线命令和曲线命令划分开,依次讲解其含义。
直线命令的意思就是通过两个点画他们之间的直线。
注意:以下所有命令中 大写为绝对定位 小写为相对定位,后续的命令亦如此
M(Move to)
M命令其实就是把画笔移动到某个点,就好像画笔提起来以后移动到一个新的位置准备开始绘制。但因为仅仅是移动画笔而没有绘制,所以M命令经常出现在路径的起始点,用来指明画笔应该从何处开始绘制。
每一段路径都必须以M命令开头,如果有多个M命令则表示新路径的开始。
语法:M x y 或者 m x y
参数:x、y为坐标
因为M命令只是移动画笔而不画线,所以就先不给出示例,咱们结合下一个命令一起给示例。
L(Line to)
L命令会绘制一点并且和之前的点(也就是L命令前面的点)连成一条直线。
语法:L x y 或者 l x y
参数:x、y为坐标
示例:
SVG - path
复制代码
效果:
image.png
是不是觉得瞬间就明白了还觉得挺有意思?咱们继续看更有意思的。
H(Horizontal Line to)
H命令可以从之前的点绘制一条水平的直线,H命令可以等价于y值和之前点相同的L命令
语法:H x 或者 h x
参数:x为X轴坐标
示例:
SVG - path
复制代码
效果为:
image.png
V(Vertical Line to)
V命令可以从之前的点绘制一条垂直的直线,V命令可以等价于x值和之前点相同的L命令
语法:V y 或者 v y
参数:y为Y轴坐标
示例:
SVG - path
复制代码
效果:
image.png
PS:注意连续的H命令和V命令取大值
示例:
SVG - path
复制代码
效果:
image.png
Z(Close path)
Z命令是一个闭合命令,他会从当前点画一条直线到路径的起始点。
Z命令因为没有参数所以Z和z效果一样,所以不区分大小写,
语法:Z 或者 z
参数:无
示例:
SVG - path
复制代码
效果:
image.png
曲线命令顾名思义就是绘制平滑的曲线
Q(Quadratic Bezier Curve to)
Q命令可以用来绘制一条二次贝塞尔曲线,二次贝塞尔曲线需要一个控制点,用来确定起点和终点的曲线斜率。
语法:Q x1 y1, x y 或者 q x1 y1, x y
参数:x、y为终点位置,x1、y1为控制点。
咦~ 有没有到发现,参数中只有终点没有起点?其实起点就是M命令
示例:
SVG - path
复制代码
效果:
image.png
T(Smooth Quadratic Bezier Curve to)
T命令时一个延长二次贝塞尔曲线的简化命令,T命令可以通过前一个控制点推断出后一个控制点,这也就是为什么T命令只需要一个坐标的原因。
需要注意的是T命令的的前面必须有一个Q命令或者其他的T命令。如果T命令单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线
语法:T x y 或者 t x y
参数:x、y为终点位置。
示例:
SVG - path
复制代码
效果:
image.png
C(Curve to)
C命令可用来绘制一条三次贝塞尔曲线,相对于二次贝塞尔曲线多了一个控制点。
语法:C x1 y1, x2 y2, x y 或者 c x1 y1, x2 y2, x y
参数:x、y为终点位置,x1、y1为曲线起始点的控制点,x2、y2为曲线终止的控制点。
示例:
SVG - path
复制代码
效果:
image.png
S(Smooth Curve to)
三次贝塞尔曲线的S命令和二次贝塞尔曲线的T命令比较相似。S命令也可以用来创建与前面一样的贝塞尔曲线,但如果S命令跟在一个C命令或者另一个S命令的后面,那么它的第一个控制点,就会被假设成前一个控制点的对称点。
如果S命令单独使用,前面没有C命令或者另一个S命令,那么它的两个控制点就会被假设为同一个点。
语法:S x2 y2, x y 或者 s x2 y2, x y
参数:x、y为终点位置,x2、y2为曲线终止的控制点。
示例:首先先画一段曲线
SVG - path
复制代码
效果如下:
image.png
然后我们再加一段S命令看看
SVG - path
复制代码
效果为:
image.png
三次贝塞尔曲线相对于二次贝塞尔曲线拥有更大的自由度,但两种曲线能达到的效果是差不多的。最终选择使用哪种贝塞尔曲线,通常取决于需求,以及对曲线对称性的依赖程度。
A(Elliptical Arc)
A命令用于画弧形,它可以截取圆或椭圆的弧形成的曲线
语法: A rx ry x-axis-rotation large-arc-flag sweep-flag x y 或者 a rx ry x-axis-rotation large-arc-flag sweep-flag x y
参数:
rx、ry分别为X轴的半径和Y轴的半径
x-axis-rotation为弧度在X轴的旋转角度
large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧
sweep-flag为弧的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧
x、y为弧形的终点
示例:
SVG - path
复制代码
效果为:
image.png
在上面的例子中我们经常用这样的属性:
fill="none" style="stroke: #ff0000"
复制代码
我想大家看着肯定也会想这是啥玩意?其实这就是我们接下来要说的内容。
fill属性用于填充图形的颜色
语法:fill= "colour" 或者 style="fill: colour"
示例:
SVG - fill
复制代码
效果:
image.png
从上面的示例中可以看出,在不设置fill属性的时候,其实默认是黑色的填充,这也就是为什么上面的很多例子我们设置了 fill='none'
其实就是去掉默认填充。
fill属性其实还有一些延伸属性:
fill-opacity属性用于设置填充颜色的透明度
示例:
SVG - fill
复制代码
效果:
image.png
fill-rule属性用来设置复杂形状的填充规则。它有两种填充方式:nonzero 和 evenodd。该属性简单说就是判断某点属于该形状的“内部”还是“外部”。那么判断的规则是什么呢?
nonzero
nonzero为默认值,规则为:要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数,路径从左向右(顺时针)穿过射线则计数加1,从右向左(逆时针)穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。
是不是感觉还是有点懵?举个例子看一下。
示例:
SVG - fill
复制代码
PS:上面示例中的绿色三角形只是用来辅助理解的,可以忽略,咱们只需要了解规则是如何填充的就行。
效果图:
image.png
evenodd
规则为:要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。
直接看示例吧:
示例:
SVG - fill
复制代码
PS:上面示例中的绿色三角形只是用来辅助理解的,可以忽略,咱们只需要了解规则是如何填充的就行。
效果为:
image.png
stroke属性用来定义线条、文本或元素轮廓的颜色。
语法:stroke="colour" 或者 style="stroke: colour"
示例:
SVG - stroke
复制代码
效果:
image.png
stroke属性也有一些延伸属性,下面依次介绍一下。
stroke-width属性定义了轮廓的宽度
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-opacity属性用于设置轮廓的透明度
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-linecap属性定义了轮廓终点的形状,该属性有三个值:
butt:默认值,以直边结束线段
round:以圆角结束线段,圆角的半径由stroke-width(轮廓宽度)控制的
square:也是以直边结束线段,但和butt不同的是会在结束位置多出一段由stroke-width(轮廓宽度)大小控制的长度。
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-linejoin属性定义了轮廓连接处的样式。样式有三种类型:
miter:默认值,表示用方形画笔在连接处形成尖角
round:用圆角连接,实现平滑效果
bevel:连接处会形成一个斜面
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-dasharray属性可以定义轮廓为虚线
语法:stroke-dasharray="xxx"
参数:xxx为一列数字字符串,对应的是:线段 空格 线段 空格......
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-dashoffset
stroke-dashoffset 属性用于指定路径开始的距离。值可为正值、负值、百分比。
示例:
SVG - stroke
复制代码
效果:
image.png
stroke-miterlimit
如果两条线交汇在一起形成一个尖角,而且属性 stroke-linejoin 指定了 miter,斜接有可能扩展到远远超过路径轮廓线的线宽。属性 stroke-miterlimit 对斜接长度和stroke-width的比率强加了一个极限。当极限到达时,交汇处由斜接变成倒角。
示例:
SVG - stroke
复制代码
效果为:
image.png
SVG中我们不仅可以绘制各种图形,我们还可也以绘制文字。
通过text标签我们可以在SVG中添加文字,
示例:
SVG - 文字
复制代码
效果为:
image.png
从上面的实例我们可以看到,text标签有一些自己的属性,下面我们细说一下text标签的属性。
x和y属性决定了文字的绘制起点。如上面的例子我们就是从坐标(50,50)的位置开始绘制的文字。
但需要注意的是x和y的值可以是一个数列。如果设置为了一个数列则会应用到每一个字符上
示例:
SVG - 文字
复制代码
效果为:
image.png
dx和dy属性与x和y属性不同的是,x和y属性是绝对的坐标,而dx和dy属性是相对于当前位置的偏移量。
参数也可以是一个数列。如果设置为了一个数列则会应用到每一个字符上
示例:
SVG - 文字
复制代码
效果为:
image.png
rotate属性可以把文字旋转一个角度。
示例:
SVG - 文字
复制代码
效果为:
image.png
同样的参数也可以是一个数列。如果设置为了一个数列则会应用到每一个字符上
示例:
SVG - 文字
复制代码
效果为:
image.png
textLength属性给定了一个字符串的计算长度。在文字的长度和textLength属性给定的长度不一致的情况下渲染引擎会精细调整字型的位置。
示例:
SVG - 文字
复制代码
效果为:
image.png
lengthadjust属性可以控制文本以什么方式伸展到由_textLength_属性定义的长度。
spacing:只拉伸或压缩间距(文字不变形)
spacingAndGlyphs:同时拉伸或压缩间距和文字本身(文字变形)
示例:
SVG - 文字
复制代码
效果为:
image.png
填充和轮廓也都可以应用于文字
示例:
SVG - 文字
复制代码
效果为:
image.png
一些CSS中的文字样式属性同样也可以应用于SVG的文字中。比如上面例子中我们用到的文字加粗:font-weight 还有很多属性同样也适用,例如:font-size、font-family、font-style、font-variant、font-stretch、font-size-adjust、kerning、letter-spacing、word-spacing、text-decoration等。
示例:
SVG - 文字
复制代码
效果:
image.png
tspan标签和text标签一样都可以用来添加文字,但不同的是tspan标签的作用为标记大块文本内的部分内容。比如一段文本其中某个字需要加粗或者颜色不一致,就可以用到tspan标签。
tspan标签的属性和text标签一致,上面说道的text标签的属性在tspan标签中也适用。
需注意的是tspan标签必须是一个text元素的子元素或别的子元素tspan的子元素。
示例:
SVG - 文字
复制代码
效果:
image.png
需要注意的是tspan标签的x、y和 dx、dy 会对标签后面的内容造成影响
示例:
SVG - 文字
复制代码
效果:
image.png
tref标签配合xlink:href
属性能引用已经定义的文本,实现复制的效果。并且引用之后还可以单独定义他的样式。
但遗憾的是 tref标签是SVG 1.1规范的内容,它已经从SVG 2.0规范中删除了。
因此此处咱们可以使用 use标签来代替它,这里说明一下:
defs标签可以定义一些之后绘制中需要重复使用的图形元素,defs是definitions的缩写 。
use标签可以在SVG文档内读取目标节点,并在别的地方复制使用。
示例:
SVG - 文字
复制代码
效果:
image.png
textPath标签可以利用它的xlink:href属性取得一个任意路径,并且可以让字符顺着路径渲染。
示例:
SVG - 文字
复制代码
效果:
image.png
了解渐变的小伙伴都知道,渐变就是从一个颜色过渡到另一个颜色,且渐变都分为两种渐变:线性渐变和径向渐变
在SVG中渐变依旧如此。
但需要注意的是这里我们需要接触两个新的标签:
defs标签用来定义渐变
stop标签用来定义渐变的颜色坡度,具有三个属性:offset定义渐变开始和结束的位置、stop-color(定义颜色)和stop-opacity(定义透明度)
线性渐变(linearGradient)就是沿直线改变颜色。
语法:
...
...
复制代码
参数:x1、y1定义线性渐变的起点, x2、y2定义渐变的终点。
示例:
SVG - 渐变
复制代码
效果:
image.png
改变x1、y1和x2、y2的值可以定义不同方向上的渐变
示例:
SVG - 渐变
复制代码
效果:
image.png
径向渐变(radialGradient)其实就是以一个点做放射性的渐变。
语法:
...
...
复制代码
参数:cx、cy、r分别为圆的坐标和半径,也就是渐变的范围,fx、fy定义渐变的中心点,也叫渐变的焦点。
示例:
SVG - 渐变
复制代码
效果:
image.png
不管是线性渐变还是径向渐变,他们不仅可以用于图形还是用于文字
示例:
SVG - 渐变
复制代码
效果:
image.png
同样的渐变不仅可以用来填充(fill),还能用来绘制轮廓(stroke)
示例:
SVG - 渐变
复制代码
效果:
image.png
裁剪和蒙层是我们在之后的SVG应用中常用的功能之一。总而言之是一些特定场景必不可少的功能。
裁剪的功能主要是使用clipPath
标签定义一条裁剪路径,然后用来裁剪掉元素的部分内容。且任何透明度的效果都是无效的,它只能要么裁剪掉要么不裁剪。
示例:
SVG - 裁剪
复制代码
效果:
image.png
蒙层的功能主要实现标签就是mask
标签,他的功能和名字正好相反,他不是用来遮住元素的部分内容,而是用来显示元素中mask
标签遮住的内容。他和clipPath
标签不同的是他允许使用透明度(透明度为0则无蒙层效果)和灰度值遮罩计算得的软边缘
示例:
SVG - 裁剪
复制代码
效果:
image.png
盼星星盼月亮终于盼到了我们最期待的SVG动画的章节了。因为文章分为两部分发布的,上周末只发布了一些基础的东西,所以就有小伙伴在评论里催动画方面的知识点,这周末咱们就一起来看看。
在做动画之前呢咱们需要先了解一下动画的基础知识。咱们再学习CSS的时候其实都有学过,大概就是平移、缩放、旋转等一些transform属性的一些方法。下面我们依次说一下,就算是做动画之前的一个小复习吧。
translate()方法主要的功能就是用来平移的,把元素从一个地点平移到另一个地点。
语法:transform="translate(x, y)"
参数:x为X轴上的平移距离,y为Y轴上的平移距离,
示例:
SVG - 动画
复制代码
效果:
image.png
scale()方法可以用来缩放元素,通过缩放来控制元素的大小。
语法:transform="scale(x, y)"
参数:x为X轴上的缩放大小,y为Y轴上的缩放大小,当两个值一样时,写一个值就可以。
示例:
SVG - 动画
复制代码
效果:
image.png
rotate()方法可以用来做元素的旋转功能,把元素从一个地点平移到另一个地点。
语法:transform="rotate(deg)"
参数:deg为旋转的角度,45度就写45度。
示例:
SVG - 动画
复制代码
效果:
image.png
是不是觉得效果和我们想想中的不一样?我就只想旋转,为什么感觉还发生了位移呢?
其实这是因为元素的旋转中心点是(0, 0)。如果我们想要只是选中而不位移,那么就需要把旋转的中心点设置在元素的中心点。
以上面的例子为例,元素的x坐标为200,本身宽度为100,则x轴元素的中心点就为250,y轴元素的坐标为0,高度为100,则y轴元素的中心点为50。因此元素的中心点就为(250, 50)。
transform-origin
上面我们已经得到了元素的中心点,那么如何设置元素的中心点呢?
我们需要通过transform-origin
属性来设置元素的中心点。直接看例子:
SVG - 动画
复制代码
效果:
image.png
skew()方法可用来实现元素的倾斜,可根据参数去分别做X轴和Y轴的倾斜度。
语法:transform="skewX(x) skewY(y)"
参数:x为X轴上的倾斜度,y为Y轴上的倾斜度。
在SVG中skew属性需要分开设置,x轴设置为skewX,y轴设置为skewY,不能合并起来用,写成 skew(x, y) 是不生效的。
示例:
SVG - 动画
复制代码
效果:
image.png
在文章最开始的时候我们就说过:SVG不能动态的修改动画内容。
所以CSS3的过渡属性就不好使了,那么想实现动画就只能使用js的定时器(setInterval)来实现。
举个例子:
SVG - 动画
复制代码
效果:
未标题-1.gif
那么SVG最拿得出手的线条动画又如何用js来实现呢?比如我们需要变换图形:
示例:
SVG - 动画
复制代码
效果:
未标题-2.gif
是不是越来越有SVG的样了?
但不幸的是,用js操作真的是很费劲。加入我们这个不是直线变三角再变菱形,而是正方形变十边形再变圆形最后变五角星。你想想这个计算是不是很头大?那有没有什么简单的方法呢?
这个问题我们先留着,接下来我们看看CSS3配合SVG做动画会怎么。
下面我们就结合CSS来尝试做一下svg的线条动画。这里我们需要用上三个属性:分别是 stroke
、stroke-dasharray
、stroke-dashoffset
。
首先咱们先看一下如何把线条动起来。
示例:
SVG - 动画
复制代码
效果:
未标题-4.gif
那么咱们就按照这个逻辑搞一个按钮的线条动画吧。
示例:
SVG - 动画
复制代码
效果:
bai.gif
我们可以把填充和轮廓弄一些填充,效果就更好看了
示例:
SVG - 动画
复制代码
效果:
cai.gif
到此我们就看完了SVG分别用js和css来实现动画的方法。那是不是觉得都比较繁琐呢?首先想绘制一个复杂的SVG就很复杂,其次用js去变化坐标也很复杂,用css去做动画简单点,但实现的动画也相对简单。
那么有没有什么“捷径”可以走呢?那回答肯定是:必须有啊!
GreenSock[4] 动画平台 (GSAP) 是一个业界知名的工具套件,用于 超过 1100 万个网站,其中包括超过 50% 的 获奖网站 !您可以使用 GSAP 在任何框架中为 JavaScript 可以触及的几乎所有内容制作动画。无论您是想要为 UI、SVG、Three.js 还是 React 组件制作动画,GSAP 都能满足您的需求。核心库 包含创建超快速、跨浏览器友好动画所需的一切。这就是我们将在本文中逐步介绍的内容。
除了核心,还有各种插件。您无需学习它们即可开始,但它们可以帮助解决特定的动画挑战,例如 基于滚动的动画、 可拖动 交互、变形等。
image.png
本文以SVG为主,所以不做太多GSAP的概述,我们直接说一下如何把GSAP应用到SVG动画中把。
// 引入 CND 地址
复制代码
下面介绍一下GSAP的使用和常用方法。
先举个例子看一下。
示例:
SVG - 动画
复制代码
效果:
g1.gif
如上面的例子可以看出,我们只需要一个 .to()
方法就可以实现我们想要的动画。而像 .to()
方法这样的补间类型还有三个:
补间有四种类型:
gsap.to():这是最常见的补间类型。.to()补间将从元素的当前状态开始 “到” 补间中定义的值。
gsap.from():和 .to() 正好相反,.from()补间中定义的值 为动画开始的状态。
gsap.fromTo():定义了起始值和结束值。
gsap.set():立即设置属性(无动画)。
接下来我们将应用这几个补间类型实现一些酷炫点的动画。
案例1:下拉松开以后的回弹动效
SVG - 动画
复制代码
效果:
未标题-5.gif
案例2:小球物理落地动画
SVG - 动画
复制代码
效果:
未标题-7.gif
以前咱们是看不懂SVG里面的哪些标签和path路径,那么现在能看懂是不是又觉得写不出一个好看的SVG呢?
其实这是正常的,都啥时代了,能用工具的绝不自己动手,下面咱们就说一下,如何应用工具和插件,写一个酷炫的SVG动画。
能生成SVG路径的工具还是比较多的啊,比如你想要现成的SVG图标,咱们可以直接上 iconfont下载就完事了【大体的流程就是:进入iconfont网站 -> 找到你想要的图标 -> 鼠标滑到图标上点击下载 -> 然后选择SVG下载】。
一些复杂的svg路径呢我们可以用 Sketch 或者 AI 之类的工具生成,比如说下面我们要做一个飞机划过的动画:
首先 我们在iconfont中找一个飞机的图标,如图:
image.png
然后我们把下载下来的svg图片添加到我们的案例中:
复制代码
上面这个就是小飞机的svg文件,添加到项目中就是这样
image.png
然后咱们再用Sketch弄一个飞机飞行轨迹的路径:
1.gif
飞机和运动轨迹的svg都加入项目中以后,我们还需借助一个GSAP的插件(MotionPathPlugin)来实现这个功能。
示例:
SVG - 动画
复制代码
效果:
feiji.gif
我们把运动轨迹隐藏看一下效果会发现更好。
feiji3.gif
接下来我们做一个图形变换的例子。同样的用Sketch创建几个图形的路径:
按照上面的操作创建了三角形、矩形、五角星和,然后再在iconfont中找了一只猫和一只狗。下面我们就看一下他们之间的图形变换动画。
首先说一下我们需要用到的一个GSAP的方法:timeline()
,其次还用到了另一个GSAP的插件:MorphSVGPlugin3
和名字一样,它是用来创建一条时间线的。
直接上示例:
SVG - 动画
复制代码
效果为:
bian.gif
最后咱们看一个文字描边动画,今天天气不错,但我只能在家码字。所以就来一个"今天天气不错!"吧。
首先文字的轮廓咱们需要借助AI软件来创建,不然自己写我是写不出来。
上教程:
gif太快还不清楚,需要的可以看视频:今天天气不错创建轮廓[5]
拿到轮廓以后就开始写动画了。
SVG - 动画
复制代码
效果:
jintian.gif
到此咱们SVG的基础内容就打算完成了。
感兴趣的兄弟们记得三连哦~ 非常感谢!