共计 13380 个字符,预计需要花费 34 分钟才能阅读完成。
本文作者:钱鸿昌(闪火)
一、咱们为什么应用 svg
-
和高清 png 来做个比照
持续比照
同样高清的质地,矢量图不畏惧放大,体积小。这里要阐明一点就是,因为 SVG 中保留的是点、线、面的信息,与分辨率和图形大小无关,只是跟图像的复杂程度无关,所以图像文件所占的存储空间通常会比 png 小。
- 优化 SEO 和无障碍的利器,因为 SVG 图像是应用 XML(可扩大标记语言【英语:Extensible Markup Language,简称:XML】标记指计算机所能了解的信息符号,通过此种标记,计算机之间能够解决蕴含各种信息的文章等)来标记构建的,浏览器通过绘制每个点和线来打印它们,而不是用预约义的像素填充某些空间。这确保 SVG 图像能够适应不同的屏幕大小和分辨率。
- 因为是在 XML 中定义的,SVG 图像比 JPG 或 PNG 图像更灵便,而且咱们能够应用 CSS 和 JavaScript 与它们进行交互。SVG 图像设置能够蕴含 CSS 和 JavaScript。在 react、vue 这种数据驱动视图的框架下,对于 SVG 操作就更加蛟龙得水了。(下文会跟大家分享一些小的 SVG 动画在咱们我的项目中的实际)
- 在使用层面上,SVG 提供了一些图像编辑成果,比方屏蔽和剪裁、利用过滤器等等。并且 SVG 只是文本,因而能够应用 GZip 对其进行无效压缩。
二、理解 SVG 罕用元素及其应用
大多数教程网上都能找到,这里写一些我感觉值得提及的点
2-1. svg 标签
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="49" stroke="black"
stroke-width="2" fill="red" />
</svg>
这就是咱们从设计手里拿到的 SVG 源文件,咱们掰开揉碎了说。首先咱们把 SVG 外部代码全副去掉不看,于是成了这样
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
这是 99% SVG 都会体现进去的模式和及一些属性,其中蕴含 width、height 这两个视口属性,viewBox 视图属性,xmlns 属性。咱们一行一行看
第一行:蕴含了 XML 申明,XML 申明其实和 HTML 文档的 DTD 申明是相似的。类比 HTML5 的申明形式
<!DOCTYPE html>
SVG 的文档申明形式(划重点:个别如果 SVG 使用在 HTML 里,咱们能够不写这样的文档申明,但如果是独自的 SVG 文件,那就须要写了,否则浏览器可能会不意识)
<?xml version="1.0" standalone="no"?>
咱们看到的 standalone 属性是在表明该 xml 申明是否是独立的,如果不是即 standalone=”no”,那前面会引入内部的 dtd,如第二行第三行所示。version 属性用于指明 SVG 文档遵循标准的版本。它只容许在根元素<svg>
上应用。它纯正是一个阐明,对渲染或解决没有任何影响。尽管它承受任何数字,然而只有 1.0 和 1.1. 这两个无效的抉择。
第四行:这是 SVG 内容的开始
<svg width="300" height="300" viewBox="0, 0, 100, 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
-
xmlns 属性是 SVG 的 XML 申明空间,这一部分相似于 HTML 中的 xmlns=”http://www.w3.org/1999/xhtml”
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
width & height 属性,能够了解成画布的大小。没错是画布的大小。举个例子:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=100 height="100"> <circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" /> </svg>
以后这个 SVG 的画布大小是 100 * 100 的画布,咱们画上一个半径为 49 再加 1 个单位的描边的圆。刚好撑满没故障。所见即所得。那咱们试一下扭转 width 和 height。发现
<svg
style="background:#007fff"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="300"
height="300">
<circle cx="50" cy="50" r="49" stroke="black"
stroke-width="1" fill="red" />
</svg>
咱们能够看到蓝色区域就是咱们定的 width 和 height , 图形局部仍然是那个圆没有变动。这样咱们就了解了 width 和 height 的作用。
-
viewBox 属性,接下来配合 viewBox 这个属性咱们再来批改下代码
<svg style="background:#007fff" xmlns="http://www.w3.org/2000/svg" version="1.1" <!-- viewBox 定义 --> viewBox="0, 0, 100, 100" width="300" height="300" > <circle cx="50" cy="50" r="49" stroke="black" stroke-width="1" fill="red" /> </svg>
咱们能够看到蓝色区域大小不变,而咱们的圆却变得很大,大到撑满了整个画布。没错,你的想法是对的,所谓 viewBox 这个属性能够了解为咱们微信聊天时的截图操作。viewBox 属性的四个参数,前两个示意截图终点,前面两个示意截图起点,均是以左上角定点为原点。最初把截图再拉伸放在 SVG 画布上,就成了咱们下面看到的 SVG 了。上面咱们再批改一次 viewBox 成 0, 0, 50, 50 帮忙了解
<svg
style="background:#007fff"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0, 0, 50, 50"
width="300"
height="300" >
<circle cx="50" cy="50" r="49" stroke="black"
stroke-width="1" fill="red" />
</svg>
所以整个逻辑大略是这样的
2-2.path 标签
在 SVG 里,你能够把 path 看成是最根本的绘制元素,正因为它是最根本的,万变不离其宗,他能演化出各种简单的绘制成果。所以 path 是最根本也是最简单的绘制元素。
path 的根底属性和其代表的意义
咱们晓得一个 path 标签,最重要的属性是 d 属性,它是一组指令和参数的汇合。在 d 属性的值里,咱们能看到一堆非常复杂的指令字符串。
<path d="
M73.8616812,68.8664775
L74.5015359,74.5939423
L68.1746283,71.7969507
C66.2299599,72.4159872 64.1377269,72.7711218 61.9444643,72.7711218
C51.9719158,72.7711218 43.8883163,65.7823167 43.8883163,57.1611168
C43.8883163,48.5399169 51.9719158,41.5511118 61.9444643,41.5511118
C71.9164005,41.5511118 80,48.5399169 80,57.1611168
C80,61.8286883 77.6181486,66.006419 73.8616812,68.8664775"id="Fill-1"fill="#FFFFFF"></path>
其实齐全不必感觉恶心,这里持续掰开揉碎了说
- d 属性里的那些指令
指令 | 参数 | 含意 |
---|---|---|
M | x y | 将画笔挪动到点(x,y) |
L | x y | 画笔从以后的点绘制线段到点(x,y) |
H | x | 画笔从以后的点绘制程度线段到点(x,y0),y0 示意绘制前画笔所在 y 轴坐标,也就是 y 轴不变 |
V | y | 画笔从以后的点绘制竖直线段到点(x0,y),x0 示意绘制前画笔所在 x 轴坐标,也就是 x 轴不变 |
A | rx ry x-axis-rotation large-arc-flag sweep-flag x y | 画笔从以后的点绘制一段圆弧到点(x,y) |
C | x1 y1, x2 y2, x y | 画笔从以后的点绘制一段三次贝塞尔曲线到点(x,y) |
S | x2 y2, x y | 非凡版本的三次贝塞尔曲线(省略第一个控制点) |
Q | x1 y1, x y | 绘制二次贝塞尔曲线到点(x,y) |
T | x y | 非凡版本的二次贝塞尔曲线(省略控制点) |
Z | 无参数 | 绘制闭合图形,如果 d 属性不指定 Z 命令,则绘制线段,而不是关闭图形 |
以上是 path 门路中的全副指令,其中加粗局部为罕用根底指令,相对来说比拟好了解。每个指令都有对应的小写指令。例如 M 10,10 有对应的 m 10,10。大写代表相对地位,所谓相对地位即对 SVG 画布左上角原点的相对 。小写代表绝对地位, 所谓绝对地位是以以后画笔所在位置进行定位。
-
A(arc)画弧指令
A rx ry x-axis-rotation large-arc-flag sweep-flag x y <svg width="100%" height="100%"> <path d="M0 0 A 45 45, 0, 0, 0, 45 45 L 45 0 Z" fill="green"/> </svg>
画了张图,帮忙了解
依照图中的步骤,咱们能够画出两个圆都满足,于是再看到其中 A 指令有三个 0 咱们没有解释,回顾下 A 指令,并联合这张图咱们能够更好的了解
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
- 贝塞尔曲线
对于贝塞尔曲线,张老师这篇文章曾经说得十分分明了,说得十分易懂深度了解 SVG 门路,举荐给心愿更多理解 svg 门路的同学
2-3. 根本图形
根本图形这块绝对比拟好了解,咱们间接一张表总结下,不做过多赘述
图形 | 标签 | 模板 | 含意 |
---|---|---|---|
矩形 | < rect > | <rect x="60" y="10" rx="10" ry="10" width="30" height="30"/> |
x: 终点横坐标,y: 终点纵坐标,rx: 倒角 x 轴方向半径,ry: 倒角 x 轴方向半径,width: 宽度,height: 高度 |
圆形 | < circle > | <circle cx="100" cy="100" r="50" fill="#fff"></circle> |
cx: 圆心横坐标,cy: 圆心纵坐标,r: 半径 |
椭圆 | < ellipse > | <ellipse cx="75" cy="75" rx="20" ry="5"/> |
cx: 椭圆心横坐标,cy: 椭圆心纵坐标,rx: 椭圆 x 轴方向半径,ry: 椭圆 y 轴方向半径 |
直线 | < line > | <line x1="10" x2="50" y1="110" y2="150"/> |
x1,y1: 终点,x2,y2: 起点 |
折线 | < polyline > | <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/> |
每两个点以空格配对为一个坐标点,逗号隔开造成坐标汇合。连成折线。 |
多边形 | < polygon > | <polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/> |
相似折线,不同的是,最初一个点会主动闭合第一个点,造成闭环。 |
2-4.symbol 标签
symbol 标签是咱们直播团队 icon 治理平台实现的核心技术点,它的作用说文言点就是相当于是一个元件,放在咱们的工具箱里,就像上面这样:
<svg class="svg-sprite">[工具箱]
<symbol id="icon-wave_add" viewBox="0 0 76 76"><path d="M38 0a4 4 0 014 4v30h30a4 4 0 110 8H41.999L42 72a4 4 0 11-8 0l-.001-30H4a4 4 0 110-8h30V4a4 4 0 014-4z" fill="currentColor" fill-rule="evenodd" opacity="none"></path></symbol>
<symbol id="icon-time" viewBox="0 0 10 10"><path d="M5 0a5 5 0 110 10A5 5 0 015 0zm0 1.5a.5.5 0 00-.5.5v3.02l.008.088a.5.5 0 00.238.343L7.02 6.794l.082.039a.5.5 0 00.603-.215l.039-.082a.5.5 0 00-.216-.603L5.5 4.735V2l-.008-.09A.5.5 0 005 1.5z" fill="rgba(153,153,153,1)" fill-rule="evenodd" class=" "></path></symbol>
<symbol id="icon-wave_delete" viewBox="0 0 40 40"><g fill="none" fill-rule="evenodd"><circle fill="#000" opacity="0.2" cx="20" cy="20" r="20"></circle><path stroke="#FFF" stroke-width="4" stroke-linecap="round" d="M13 13l14 14M27 13L13 27"></path></g></symbol>
</svg>
放一份就能够有限援用。当它在工具箱里时,咱们是看不到它的(页面不会渲染它),只有咱们应用了 <use>
标签对其进行实例援用时,咱们才能够在页面上看到它:
<use xlink:href="#icon-time"></use>
咱们应用 <symbol>
+ <use>
的组合,来实现 svg 雪碧图,是不是感觉很 easy。
有的同学会有疑难,symbol 标签和 g 标签,放在 defs 里好像都是在定义一个可复用的模块,那么两者之间有什么区别呢?在我的了解里,symbol 绝对于 g 标签最大的不同在于 symbol 能够给可复用代码块减少视图属性和视口属性。不便在服用的时候间接调整到适合的使用 (打印) 尺寸。
三、svg 动画及其使用
3-1.svg 动画概要
其实对于 SVG 动画,要说的有很多,本文咱们次要说一下 SVG 动画的一些根本属性和使用技巧
1、SMIL 驱动
2、JavaScript 驱动
3、CSS 驱动
技术 | 形容 | 备注 |
---|---|---|
SMIL | 很弱小且纯正的标签化动画 | 尽管 Chrome 45 当前弃用了 SMIL,然而仍然反对,各大浏览器的反对度都挺好的 |
CSS | CSS 还只能实现简略的动画 | offset-path 的兼容性很差。css 动画不适宜做交互性很强的动画 |
JavaScript | 简单动画就要用到 JS 了,包含世面上的一些 SVG 动画库,也都是 JS 去实现的 | – |
SVG 是基于 XML 的矢量图形描述语言,能够近似了解成 HTML,所以能和 JS 以及 CSS 进行交互。特地是 CSS,咱们能够应用 CSS3 来对 SVG 做动画解决。然而要记住的是仅当 HTML 内联蕴含 SVG 文件时, 咱们才能够应用 CSS 对其做款式开发。本文咱们针对平时 CSS3 + HTML 不容易实现,而利用 SVG 能够疾速简便实现的几种场景做相应介绍
3-2.SVG 动画实际
1、直线的变动
2、path 门路实现图形的平滑变幻
3、描边动画
4、指定轨迹静止
3-2-1、直线的变动
上面这张图是一个 GIF 的 icon, 体积大概是 156KB, 压缩之后。
如果咱们用 SVG 去实现的话。应该怎么做呢。咱们分为以下两种形式,亲测兼容性都 OK
CSS+SVG 实现的代码实际
基于 SMIL 实现的代码实际
总结 & 阐明:
知识点 1:
SVG 中有很多属性咱们是能够用 CSS 去形容的。在基于 CSS 动画三剑客(animation, transform, transition)的根底上。咱们对一些属性进行管制,就达到咱们想要的动画成果。上面两点值得阐明:
- transform:transform 有两种用法,一个是在 SVG 标签里写的 transform 属性、另一种是在 CSS 文件里写的 transform,他们有着实质的区别。
<rect transform="rotate(45deg) ..." ... />
rect {transform: rotate(45deg)
}
/** 行内的 transform 属性,他的执行基点是在咱们 svg 元素的左上角也就是 svg 的坐标原点。**/
/** 而 CSS 的 transform 原点则在元素自身的中心点。**/
-
CSS 可形容属性:很多文章通知咱们 CSS 能够管制 SVG 去做动画,然而理论开发过程中咱们会更想晓得,到底哪些属性咱们能够做 css 管制,这里给大家列出一些罕用属性并且能够放心使用的属性
| CSS 可控属性名 | 可实现场景
| — | — |
| 实践上所有的显示属性,都能够应用 CSS 管制包含:比方 stroke-width、color、fill 等等 SVG 的显示属性 | 大部分的显示款式动态变化
|x| 咱们晓得矩形有 x、y 属性,其含意是起始点,管制 x,咱们能够动态控制矩形的 X 轴位移
|y| 管制 y,咱们能够动态控制矩形的 Y 轴向位移
|cx|<circle cx="100" cy="100" r="50" fill="#fff" />
这是一个圆形,管制 cx 能够管制圆形 (或者椭圆) 的 X 轴位移 |
|cy| 管制 cy 能够管制圆形 (或者椭圆) 的 Y 轴位移
|r|r 是圆的半径,管制 r 能够管制圆形的大小
|rx|rx 是椭圆的 X 轴方向半径,管制 rx 能够管制椭圆的大小
|ry|ry 是椭圆的 Y 轴方向半径,管制 ry 能够管制椭圆的大小
|d|path 标签的 d 属性,管制 d 的门路信息,能够管制图形的变幻(d 属性在 safari 上是不反对 css 形容的。咱们下文会具体的阐明)|
|PS: 如果各位看官们在日常开发中,不分明该属性是否能够通过 css 去管制,这边给大家提供一个查问链接 | 不反对 CSS 管制的 SVG 相干属性
知识点 2: 能够利用 SMIL 对 SVG 做动画解决,举个例子,同样的动画成果,上面这段代码不必 CSS 也能够实现
export default function App() {
return (
<div className="App">
<svg width="100%" height="100%" viewBox="0 0 100% 100%">
{[1, 2, 3, 4, 5].map((it, index) => (
<line
key={index}
stroke="#000"
strokeWidth="2"
x1={15 + index * 5}
y1="8"
x2={15 + index * 5}
y2="22"
>
<animate
attributeName="y1"
values="8; 15; 8"
dur="1s"
begin={`${(5 % (index + 1)) * 0.2}s`}
repeatCount="indefinite"
/>
<animate
attributeName="y2"
values="22; 15; 22"
dur="1s"
begin={`${(5 % (index + 1)) * 0.2}s`}
repeatCount="indefinite"
/>
</line>
))}
</svg>
</div>
);
}
那么
什么是 SVG 的 SMIL 呢?
这里不想再对其做大篇幅的赘述,因为网上有很多文章都曾经说得比拟具体了[SMIL 动画指栏](https://css-tricks.com/guide-svg-animations-smil/)、[SVG SMIL animation 动画详解](https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/)。本文更想和大家交换的是在 SMIL 驱动和 CSS 驱动如何做抉择的问题。
尽管说早在 Chrome 45,chrome 就曾经官宣要弃用 SMIL,然而到目前地位,各大浏览器厂商对它的反对度是这样的
Chrom 发表弃用 SMIL 是因为要反对 CSS Animation 与 Web Animation 的倒退,所以咱们能够了解为以后是在一个过渡状态,的确有一些临时 CSS 还没法反对或者反对度很差的动画成果,SMIL 能够轻松实现。然而基于 web 动画技术倒退的大趋势,还是倡议咱们 SVG 动画实现计划的抉择优先级是 CSS 驱动 -> JS 驱动(咱们能够采纳一些框架,文末会给大家举荐一些好用的框架)-> SMIL 驱动
3-2-2、path 门路的变动(图形平滑变动)
CSS+SVG 实现的代码实际 Logo 变动
基于 SMIL 实现的代码实际 Logo 变动
CSS+SVG 实现的代码实际播放暂停
基于 SMIL 实现的代码实际播放暂停
总结 & 阐明:
知识点 1:
通过对 <path/>
d 属性的管制,咱们能够实现很多动画成果,对于 d 属性的管制目前有两种形式,一种是通过 CSS 管制,另一种是通过 SMIL 管制,然而目前因为 safari 不反对 用 CSS 来形容 <path>
标签的 d 属性。所以在实现这种平滑的形态变形成果上不举荐应用 CSS。更加举荐应用 SMIL 或者第三方库去实现
基于 CSS:
path {
transition: ease all 0.3s; // 就像对 dom 一样的看待 svg
&.play { // 这里是播放状态下的 <path /> 门路
d: path("M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z");
}
&.pause { // 这里是播放状态下的 <path /> 门路
d: path("M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z");
}
}
基于 SMIL(即通过 <animate>
实现对<path>
d 属性的动态控制):
const pathMap = {
from: "M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z",
to: "M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z"
};
<svg class="icon" viewBox="0 0 120 120" width="400" height="400">
<path
d="M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z"
fill="#000000"
>
<animate
attributeName="d"
from={play ? pathMap.from : pathMap.to}
to={play ? pathMap.to : pathMap.from}
dur="0.3s"
begin="indefinite" // 这里设置开始工夫为有限以达到不自动播放的成果
fill="freeze"
/>
</path>
</svg>
以上两个 path 门路的切换,就能够带来这种平滑过渡的成果。
知识点 2:
咱们看到的图形变幻,都须要遵循一个准则就是点数对齐准则,什么意思呢?咱们能够看上面的 demo,五角星到 10 边形(多边形画的不好,道歉 …😜)。,都是 10 个控制点到 10 个控制点的适度。所以成果平滑
而下图的 10 个点到 3 个点就没有这种平滑的过渡成果了 (当然当初很多的 SVG 动画框架曾经解决了这个问题。 见文末的框架举荐 )
3-2-3、描边动画的利用
CSS+SVG 实现的代码实际 - 星环
CSS+SVG 实现的代码实际 - LOGO 描边
基于 SMIL 实现的代码实际 - 进度环
总结 & 阐明:
知识点 1:
相似的描边动画咱们能够拿来做很多成果,比方各种形态的进度条、比方文字的描边、比方霓虹灯流水灯光等等流动动画成果。而描边动画的外围点就在于 SVG 的两个显示属性别离是 stroke-dasharray、stroke-dashoffset,咱们上文说了,简直所有的显示属性都能够用 CSS 去管制,所以这种动画,倡议应用 CSS 去开发。
属性 | 值举例 | 形容 | 反对范畴 |
---|---|---|---|
stroke-dasharray | 1 3 4 4 | 它的值是一个序列,能够传入多个值,别离指定描边短线的长度和描边线间距,多个值顺次循环,如果传入 3 个值,相似于 stroke-dasharray: 1,2,3。则会主动复制一份再失效 | <circle>, <ellipse>, <line>, <mesh>, <path>, <polygon>, <polyline>, <rect> <altGlyph>, <altGlyphDef>, <altGlyphItem>, <glyph>, <glyphRef>, <textPath>, <text>, <tref>, <tspan> |
stroke-dashoffset | 10 | 描边线段的起始地位间隔图形绘制终点的偏移量。正负值能够决定顺时针还是逆时针走向 | 跟 stroke-dasharray 统一 |
构想一个场景,一个倒计时须要从 100 到 0,对应的视觉效果也就是从全描边到无描边。那么咱们初始状态将 stroke-dasharray 的第一个值设为 2πr (周长),第二个值设也设为 2πr (周长)。那么咱们会失去一个整圆。
这时如果咱们把圆开展就能看到这样的场景
所以要实现进度的动态变化其实有两种计划
第一种是将 stroke-dasharray 的第一个值从 2πr(周长)调整到 0。原开展图中的彩色局部没有了(能够了解为变成了一个点如下图,看不见了),只剩下虚线局部是空白间隙了。
第二种是将 stroke-dashoffset 的值从 0 调整到 -2πr(或者减少到 2πr)。比照第一张图成下图的样子
知识点 2:
在理论开发中,咱们会遇到一些比较复杂的图形须要做描边,这个时候咱们没方法去失去它的周长是多少,这时候分两种场景解决。一种是在 CSS 里咱们能够将 stroke-dasharray 的第二个值设置成一个十分大的数字,而后再去调整第一个值比方:
path {stroke-dasharray: 0(调整到适合的值) 99999999999999
}
如果在 js 里咱们须要动静去获取周长的话,SVG 提供了原生的 api 能够去获取 path 的周长。
const inPath = document.getElementById("inner-path");
console.log(inPath.getTotalLength());
ps:有些材料说该办法只能用于 <path />
,然而笔者亲测了在 safair 和 chrome 上,根本能够反对所有的根底图形以及<path />
,然而<text />
不反对,浏览器会报 not a function。
既然说到了getTotalLength()
, 那么顺带说下getPointAtLength()
。getPointAtLength,顾名思义就是依据间隔获取点坐标。意思就是依据到起始点的间隔,获取该指定间隔对应的点的坐标。坐标系原点为该图形的起始点。在一些指向型的动画上咱们可能会使用到这个 api。
3-2-4、轨迹静止动画的利用
基于 SMIL 实现的代码实际 - 轨迹静止
总结 & 阐明:
{/* 咱们将整个飞机图形元件用 g 标签包起 */}
<g transform="translate(-100, -35) scale(0.1)">
<path
d="M164.485419 578.709313L196.274694 794.731891c0.722484 5.53904 8.188147 7.224835 11.078081 2.408278l75.860772-121.377234 740.063969-363.409219L164.485419 578.709313z"
fill="#F68206"
></path>
<path
d="M2.167451 440.233302l159.668861 132.214487 857.828787-260.334901zM289.475071 679.375353l191.217309 153.407337 542.344309-518.743179z"
fill="#FF9900"
></path>
<path
d="M204.222013 800.030103l125.23048-80.677328-48.888053-39.014111-76.342427 118.4873"
fill="#D3650B"
></path>
{/* 而后在这里,咱们利用 animateMotion,去做这个轨迹静止 */}
<animateMotion
path="M 0 450 Q 150 50 250 50 Q 350 0 400 50 Q 500 50 450 200 C 300 350 250 200 500 50 C 600 50 750 200 650 250 A 50 50 0 1 1 800 50"
begin="0s"
rotate="auto"
dur="20s"
repeatCount="indefinite"
/>
</g>
这里咱们用到了 SMIL 里的<animateMotion />
,animateMotion 里的 path 属性,咱们也能够像这样去应用
<defs>
<path id="theMotionPath" d="xxx" />
</defs>
<animateMotion>
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
理论生产中,咱们这种轨迹静止的需要,是倡议应用 SMIL 去实现的,当然 CSS 也是有实现计划的《应用 CSS offset-path 让元素沿着不规则门路静止》。然而 CSS 的兼容切实不敢恭维,劝退一波。
四、写在最初
1、倡议将 CSS 动画用于无变形的过渡或简略动画。尤其是在硬件加速时。CSS 不须要加载其余资源(个别指三方库),并且悬停时的小变换能够为交互带来更好的成果。特地是当你不须要 3d、物理体感、或进行大量重叠动画成果时倡议选用 CSS。另外,CSS 不便调试也是很大的一个劣势。
2、对于较长的动画,开发时会变得非常复杂且须要花精力去调试,而 CSS 调整时间尺度很艰难,尤其是当你须要操纵一些轻微帧时,集体感觉 SMIL 更适合做有序的,简单的重叠动画群的场景。
3、对于变形的动画,倡议应用 SMIL 或者第三方库。举荐的比拟优良的三方库有以下几个。
| 库名 | 形容 |
| — | — |
| GSAP | 全称是 GreenSock Animation Platform,以前风行用 flash 的时候,GSAP 就叱咤江湖的存在,GSAP 有两个版本一个是 flash 版本,一个是 javascript 版本,也就是咱们说的 GSAP js。GSAP 速度快。GSAP 专门优化了动画性能,使之实现和 css 一样的高性能动画成果;轻量与模块化;|
| Snap.svg、SVG.js、Velocity.js | 这三个库始终会被开发者拿来比照,基本上会用 jQuery,就会应用这三个库,也就是说动手敌对,Snap.svg 更偏差于反对古代浏览器,所以它的体量也会小一些。比照 Snap.svg 来看 SVG.js,SVG.js 的写法更加的清晰,应用时会有更好的体验,且自称提供靠近残缺的 SVG 标准笼罩。Snap.svg 格调就更像一个侠客,写起来会很洒脱然而不好读,Velocity 也很弱小,简略易用、高性能、功能丰富 |
| anime.js | anime.js 尽管性能没有 GASP 弱小,然而体积很乐观,gzip 压缩完只有 9kb 左右,满足日常需要开发还是足够的 |
| D3 | Data-Driven Documents 顾名思义,更加适宜用于创立数据可视化图形场景去应用 |
4、如何应用 SMIL 进行硬件加速,应用 <animateTransform>
代替<animate>
,并设置 x、y、z 值(z 为 0)。原理与 CSS 相似,这会将元素移到它本人的层,从而在其产生静止时不会从新绘制。
参考资料
- SVG 动画指栏(SMIL)
- SVG 教程
- CSS 反对的 SVG 属性查寻
- 以及文章内提及的一些文章
本文公布自 网易云音乐大前端团队,文章未经受权禁止任何模式的转载。咱们长年招收前端、iOS、Android,如果你筹备换工作,又恰好喜爱云音乐,那就退出咱们 grp.music-fe(at)corp.netease.com!