让SVG 自己动起来!SMIL animation动画详解
今天一起来了解一下,怎么在不靠其它套件的状况下,单纯的制作SVG动画。
资料来源: https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/
SVG animation with SMIL
能让SVG
不靠JavaScript与CSS
就能动起来是因为使用了SMIL(Synchronized Multimedia Integration Language)
,是W3C的标准之一,旨在以XML格式提供多媒体的交互表现(白话点其实就是动画),是Web上动画的开路先锋,启发了Web animation与CSS animation。SVG与SMIL的开发团队合作,让SVG能利用SMIL达到如下效果:
- 动画化元素的数值属性(x,y值等等)
- 动画化元素的transform属性(平移、旋转)
- 动画化元素颜色
- 轨迹路线移动动画,类似于CSS中的offset-path
光是这些特性就够我们组合出很多种的动画了,还不需要JavaScript与CSS的辅助。
使用方法也不难,只要在SVG元素内置入以下四种元素即可操作动画:
<set>
<animate>
<animateTransform>
<animateMotion>
接着我们针对这四种元素一一介绍。
SVG animation element介绍与示范
\<set>
利用元素你能够指定在一段时间后,改变svg的一个属性,例如2秒后将Rick的眼睛变成往下看:
疑?你说他本来就是往下看的?
那是因为set不会重复执行,从你加载这篇文章到看到这个位置为止,相信已经超过2秒,所以已经是执行后的结果,建议你右键单击->“在新分页中开启图片”,实际体验一下,再不然看看下面的gif也行:
相关代码如下:
<circle cx=“56.7573”cy=“92.8179”r=“2”fill=“black”stroke=“black”stroke-width=“1”>
<set attributeName=“cy”to=“105.7318”begin=“2s”/>
</circle>
将元素放在你想要套用效果的svg shape内即可。
attributeName指定你要更动的属性;to代表变化值;begin代表从加载后的什么时候开始执行。
除了attributeName外,有另一个参数叫attributeType,用来告诉浏览器你要动画化的属性值是属于XML(e.g. cy),还是CSS(e.g. opacity),不指定的话,浏览器会自己猜。不过呢,这个参数也已经deprecated了,所以实际上我们不再需要它。
<animate>
<animate>
元素让你能针对单一属性变化套用动画补间效果。用法一样是放在你想要套用效果的svg shape内:
<circle cx=“56.7573”cy=“92.8179”r=“2”fill=“black”stroke=“black”stroke-width=“1”>
<animate
attributeName=“cx”from=“56.7573”to=“64.7573”
dur=“2s”repeatCount=“indefinite”/>
</circle>
与相比,多了from属性来指定要从哪个值开始做变化,dur指定动画的执行时间,repeatCount指定要重复几次,这边我们设定indefinite让他无限回放(若看不到效果请以分页开新图片):
利用animate,让Rick的眼睛向右看。
也可以用来改变颜色:
也因为可以用来改变颜色,所以本来有个元素就被取代掉了,现在已经deprecated了。
<animateTransform>
<animateTransform>
可以用来控制transform属性,用animate无法做到。跟CSS中的transform一样,可以控制translation、scaling、rotation跟skewing。
可以让 Rick 头转起来,
(注:经实测,animateTransform 在手机上似乎不支援,请用桌面版浏览器查看此范例)
<animateTransform attributeName="transform" type="rotate" from="0 0 0" to="360 0 0" begin="0s" dur="10s" repeatCount="indefinite" />
如上面所述,要控制 transform
属性,所以 attributeName="transform"
,接着 type
参数就看你想要 transform 的类型是什么,rotate
、scale
都可以。其余 from
、to
、begin
、dur
等参数都与之前的相同,用来指定动画的起始终点值、时间长度与执行次数。
<animateMotion>
最后一个元素,animateMotion
,让 svg 沿着轨迹 path 移动(若看不到效果请以分页开新图片):
<!--轨迹-->
<path d="M10,50 q60,50 100,0 q60,-50 100,0" stroke="black" stroke-width="2" /><g>
<!-- Rick 飞船 svg-->
<animateMotion path="M10,50 q60,50 100,0 q60,-50 100,0" begin="0s"
dur="10s" repeatCount="indefinite" />
</g>
上述程式码内的 <path>
只是为了让大家看清楚路径与实际动画的轨迹无关,实际使用上只要给定 animateMotion
一条 path
属性值,包含 animateMotion
元素的 svg 就会跟着该路径移动。
其他属性值跟其他元素雷同,不过 animateMotion
还有个特别的属性值 rotate
,用来指定是否要随着路径移动的同时,选转绑定的 svg 物件,可以设定为 auto
或auto-reverse
:
<animateMotion path="M10,50 q60,50 100,0 q60,-50 100,0" begin="0s"
dur="10s" repeatCount="indefinite" rotate="auto" />
此外,除了给定 path
属性值外,其实也能够利用既有的 <path>
来当作 animateMotion
的路径,但是得透过 mpath
这个 sub-element:
<!--轨迹-->
<path id="path1" d="M10,50 q60,50 100,0 q60,-50 100,0" stroke="black" stroke-width="2" /> <g><!-- Rick 飞船 svg--> <animateMotion begin="0s" dur="10s"repeatCount="indefinite"> <mpath xlink:href="#path1" /> </animateMotion>
</g>
要注意的是,若要使用 xlink:href
来指定连接的 svg 元素,在你的<svg>
tag 上得先记得宣告 xmlns:xlink="http://www.w3.org/1999/xlink"
。
<svg width="300" height="200" viewBox="0 0 500 300" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
</svg>
有了 xlink:href
,我们也就不用像之前范例中所做的一样,一定得把 animate
元素放在要绑定的 svg shape 内,可以透过 id
与 xlink:href
来连结,例如第一个<set>
的范例可改为:
<circle id="eyes" cx="56.7573" cy="92.8179" r="2" fill="black" stroke="black" stroke-width="1">
</circle> <set xlink:href="#eyes" attributeName="cy" to="105.7318" begin="2s" />
至此我们介绍完了四种 SVG animation element,除了个别拿来使用外,这些元素是能够组合在一起使用的,就只要个别把对应的 animate element 套用在想要的 svg shape 上即可,举例来说,可以让 Rick 旋转的同时,发色改变、眼睛转动(可右键看 svg 原始码,在里面可以找到多个 animate element):
SVG SMIL animation 重点参数介绍
在上面的 Demo 里面,我们可以发现 SVG animate element 有很多参数可以使用,范例中只用到了一部分,但其实这些参数能设定的值都有不少变化,想要清楚知道每一个参数的用途与范例,推荐参考这篇文章 - https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/
写得非常好非常详细。
from, to, by, values
from
跟 to
在前面的范例中都有看到,功能也如同字面般好懂,就是指定动画变化的移动区间,从(from
)某个值变化到(to
)另个值;而 by
则是代表位移量,相对于明确告知要变动到哪个值,我们可以用 by
告诉 svg 要变动”多少的量“,例如前面 animateTransform
的例子,我们可以改为:
<animateTransform attributeName="transform"
type="rotate" from="0 0 0" by="360"
begin="0s" dur="10s" repeatCount="indefinite" />
看到这边你应该会注意到,by
跟 to
功能上有点重复,所以彼此之间有优先权,如果同时有指定 to
与 by
,则只会套用到 to
的值。
再来看看 values
,这个刚刚的范例都没出现,它的功用是来补足 from
、to
、by
的不足。不足的点在于, from
、to
、by
只能指定两个值之间的变化,从 a 变化到 b,而 values
可以给定多个值,用分号;
隔开,就能有 a -> b -> c -> b -> a 这样的变化,举个例子:
<animateTransform attributeName="transform"
type="translate" values="20;120;20" begin="0s" dur="3s"
repeatCount="indefinite" />
begin, end
begin
跟 end
分别用来控制何时开始执行动画,何时停止动画,在上面的例子中我们都只用到时间,像是 begin="2s"
,但其实这两个参数能给的值有非常多的种类,而且能向 values
一样赋予多个值,只要用;
隔开即可:
begin = <offset-value> | <syncbase-value> | <event-value> | <repeat-value> | <accessKey-value> | <wallclock-sync-value>
每种类型的详细介绍,我推荐直接看网上的整理
这边我只说明几个我觉得比较实用的。
首先是 <syncbase-value>
。
从字面有点难懂,主要是用其他 animate
元素的 begin/end
值再做加减,举个例子就比较好懂:
<g> <animateTransform attributeName="transform"type="scale" values="1;1.2;1" begin="ship.end" dur="3s" repeatCount="indefinite" />
</g> <!-- spaceship -->
<g> <animateTransform id="ship"attributeName="transform" type="translate" values="20;120;20" begin="0s" dur="3s" />
</g>
这次范例中的 svg 内有两个 animate 元素,给定针对太空船做动画的元素一个 id 值 ship
,然后在 Rick 的动画元素上利用 begin="ship.end"
,就可以让 Rick 头的动画等到太空船的动画做完后再启动,效果如下:
另一个我觉得实用的值是 event-value
,看名字就知道,是可以依照 event
来启动或终结动画,用法与 syncbase-value
雷同,给定元素 id,然后根据该元素触发的事件让动画 begin
或是 end。几乎所有 DOM element 支援的 event 都能使用
最后是 indefinite
,如果你的 begin
值为 indefinite
,代表无限等待,这时就需要透过 [animate 元素].beginElement()
来触发,或是用<a>
tag 的 xlink:href="#[animate 元素 id]"
来启动。
calcMode, keyTimes, keySplines
这三个参数主要让你能够更细微的调整动画的速度变化。
calcMode
有四种模式:discrete
、linear
、paced
、spline
。
discrete 顾名思义就是离散的,from
值跳到 to
值不做补间; linear 跟 paced 我觉得效果雷同,都是让让补间动画的速度维持一致(linear)与平均(paced); spline
则是使用贝式曲线,需要搭配 keyTimes
与 keySplines
来使用。
keyTimes
就是关键影格,跟前面提过的 values
一样,可以接受多个以分号区隔的值,定义动画的关键时间点,搭配不同的 calcMode
就能在不同的时间点有不同的速度效果。
keySpline
是当你 calcMode
设定为 spline
时,用来定义贝式曲线的四个控制点的。
感兴趣的小伙伴可以直接看这篇文章:https://www.zhangxinxu.com/study/201408/svg-animation-calcmode.html
additive
看到最后,不知道你会不会有个疑问:如果我想针对同的 SVG shape 的同个属性做多个连续变化时该怎么办?
例如:透过 animateTransform
先将图案放大再位移。
这时就要靠 additive
这个参数出马了,additive
参数告知 SVG 是否要累加(sum
)动画效果,或是取代(replace
),预设是 replace
。
例子:
<animateTransform attributeName="transform"
type="scale"
by="1.1"
begin="0s" dur="5s"
repeatCount="indefinite"
additive="sum" /> <animateTransform attributeName="transform" type="rotate"
from="0 0 0" to="360 0 0"
begin="0s" dur="5s"
repeatCount="indefinite"
additive="sum" />
结论
今天花了不小的篇幅介绍了 SVG SMIL animation,感谢看到这边的各位,制作 Demo 的过程对我来说很有趣,也学习了怎么绘制 SVG,从网路上的其他资源也查到许多详细的资料,收获不少!希望对看到这篇文章的你们也能有所启发,除了常用的 Web animation 与 CSS animation 外,有机会也试试用 SVG 直接作动画吧!
资料来源:
https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/
让SVG 自己动起来!SMIL animation动画详解相关推荐
- 超级强大的SVG SMIL animation动画详解
超级强大的SVG SMIL animation动画详解 本文摘自超级强大的SVG SMIL animation动画详解_Zoomla!逐浪CMS官网 (z01.com),网站看上去有年头了,担心哪天会 ...
- [转]超级强大的SVG SMIL animation动画详解
超级强大的SVG SMIL animation动画详解 本文花费精力惊人,具有先驱前瞻性,转载规则以及申明见文末,当心予以追究. 本文地址:http://www.zhangxinxu.com/word ...
- SVG SMIL animation动画详解----转载
一.SVG SMIL animation概览 1. SMIL是什么? SMIL不是指「水蜜梨」,而是Synchronized Multimedia Integration Language(同步多媒体 ...
- SVG SMIL animation动画详解
一.SVG SMIL animation概览 1. SMIL是什么? SMIL不是指「水蜜梨」,而是Synchronized Multimedia Integration Language(同步多媒体 ...
- Android Animation动画详解(二): 组合动画特效
前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一 ...
- 第100天:CSS3中animation动画详解
CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: 一.Animation定义动画 CSS3的Animation是由"keyframes& ...
- android scaleanimation 动画方向,Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法...
一.概述 Android的animation由四种类型组成:alpha.scale.translate.rotate,对应android官方文档地址:<Animation Resources&g ...
- 超级强大的SVG动画详解
这篇文章发布于 2014年08月31日,星期日,03:07,归类于 SVG相关. 阅读 83178 次, 今日 194 次 本文花费精力惊人,具有先驱前瞻性,转载规则以及申明见文末,当心予以追究. 本 ...
- CSS动画(animation)详解
CSS动画(animation)详解 通过<CSS过渡>一节的学习我们知道,利用 transition 属性可以实现简单的过渡动画,但过渡动画仅能指定开始和结束两个状态,整个过程都是由特定 ...
最新文章
- matlab考试湖北理工学院,电子信息工程导论课程教学大纲-电气与电子信息工程学院-湖北.DOC...
- 朴素贝叶斯法分类器的Python3 实现
- idea好用的快捷键
- bp神经网络隐含层神经元个数_CNN,残差网络,BP网络
- 推给我的广告都跟我最近看的内容有关系,怎么做到的?
- C#中的i++和++i
- 如何删除textarea的移动版Safari的阴影?
- (52)多路时钟复用FPGA如何约束一(片外时钟复用约束)
- B00002 C语言位字段实例
- Servlet——文件下载
- (转)OpenStack Kilo 版本中 Neutron 的新变化
- Spring 中 AOP 的实现原理——动态代理
- matlab 删除plot上的图,matlab删除部分图例
- java 地图坐标转换_百度地图坐标和高德地图坐标转换代码 Java实现
- 佐切的第四天学习分享
- 沧海一声笑(最好版)
- 安全邮箱是什么邮箱?怎么登录163邮箱?
- CAS和自旋到底是一个概念吗?
- Vue.js学习笔记—shop-bus:实战:利用计算属性、指令等知识开发购物车
- laravel5.0学习系列1之 路由
热门文章
- 使用navicat连接mysql出现提示10038错误的解决方法
- OpencvSharp的Mat类型数组传入c++的DLL
- dijkstra算法及其堆优化
- 【maven】maven是什么?maven安装及idea中使用maven
- 再见吧 buildSrc, 拥抱 Composing builds 提升 Android 编译速度
- Tensorflow2.0的简单GCN代码(使用cora数据集)
- 超低功耗LCD液晶显示驱动芯片(IC)-VKL128-稳定性好,超低工作电流,低休眠电流-技术开发资料
- Understanding parameters:理解参数(Parameter)
- UML时序图画法简介-sequenceDiagram
- 华科博士201万,西安交大本科生100万!华为「天才少年」校招薪资曝光