今天一起来了解一下,怎么在不靠其它套件的状况下,单纯的制作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达到如下效果:

  1. 动画化元素的数值属性(x,y值等等)
  2. 动画化元素的transform属性(平移、旋转)
  3. 动画化元素颜色
  4. 轨迹路线移动动画,类似于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 的类型是什么,rotatescale 都可以。其余 fromtobegindur等参数都与之前的相同,用来指定动画的起始终点值、时间长度与执行次数。

<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 物件,可以设定为 autoauto-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 内,可以透过 idxlink: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

fromto 在前面的范例中都有看到,功能也如同字面般好懂,就是指定动画变化的移动区间,从(from)某个值变化到(to)另个值;而 by 则是代表位移量,相对于明确告知要变动到哪个值,我们可以用 by 告诉 svg 要变动”多少的量“,例如前面 animateTransform 的例子,我们可以改为:

<animateTransform attributeName="transform"
type="rotate" from="0 0 0" by="360"
begin="0s" dur="10s" repeatCount="indefinite" />

看到这边你应该会注意到,byto 功能上有点重复,所以彼此之间有优先权,如果同时有指定 toby,则只会套用到 to 的值。

再来看看 values,这个刚刚的范例都没出现,它的功用是来补足 fromtoby 的不足。不足的点在于, fromtoby 只能指定两个值之间的变化,从 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

beginend 分别用来控制何时开始执行动画,何时停止动画,在上面的例子中我们都只用到时间,像是 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 有四种模式:discretelinearpacedspline

discrete 顾名思义就是离散的,from 值跳到 to 值不做补间; linearpaced 我觉得效果雷同,都是让让补间动画的速度维持一致(linear)与平均(paced); spline 则是使用贝式曲线,需要搭配 keyTimeskeySplines 来使用。

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动画详解相关推荐

  1. 超级强大的SVG SMIL animation动画详解

    超级强大的SVG SMIL animation动画详解 本文摘自超级强大的SVG SMIL animation动画详解_Zoomla!逐浪CMS官网 (z01.com),网站看上去有年头了,担心哪天会 ...

  2. [转]超级强大的SVG SMIL animation动画详解

    超级强大的SVG SMIL animation动画详解 本文花费精力惊人,具有先驱前瞻性,转载规则以及申明见文末,当心予以追究. 本文地址:http://www.zhangxinxu.com/word ...

  3. SVG SMIL animation动画详解----转载

    一.SVG SMIL animation概览 1. SMIL是什么? SMIL不是指「水蜜梨」,而是Synchronized Multimedia Integration Language(同步多媒体 ...

  4. SVG SMIL animation动画详解

    一.SVG SMIL animation概览 1. SMIL是什么? SMIL不是指「水蜜梨」,而是Synchronized Multimedia Integration Language(同步多媒体 ...

  5. Android Animation动画详解(二): 组合动画特效

    前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一 ...

  6. 第100天:CSS3中animation动画详解

    CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: 一.Animation定义动画 CSS3的Animation是由"keyframes& ...

  7. android scaleanimation 动画方向,Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法...

    一.概述 Android的animation由四种类型组成:alpha.scale.translate.rotate,对应android官方文档地址:<Animation Resources&g ...

  8. 超级强大的SVG动画详解

    这篇文章发布于 2014年08月31日,星期日,03:07,归类于 SVG相关. 阅读 83178 次, 今日 194 次 本文花费精力惊人,具有先驱前瞻性,转载规则以及申明见文末,当心予以追究. 本 ...

  9. CSS动画(animation)详解

    CSS动画(animation)详解 通过<CSS过渡>一节的学习我们知道,利用 transition 属性可以实现简单的过渡动画,但过渡动画仅能指定开始和结束两个状态,整个过程都是由特定 ...

最新文章

  1. matlab考试湖北理工学院,电子信息工程导论课程教学大纲-电气与电子信息工程学院-湖北.DOC...
  2. 朴素贝叶斯法分类器的Python3 实现
  3. idea好用的快捷键
  4. bp神经网络隐含层神经元个数_CNN,残差网络,BP网络
  5. 推给我的广告都跟我最近看的内容有关系,怎么做到的?
  6. C#中的i++和++i
  7. 如何删除textarea的移动版Safari的阴影?
  8. (52)多路时钟复用FPGA如何约束一(片外时钟复用约束)
  9. B00002 C语言位字段实例
  10. Servlet——文件下载
  11. (转)OpenStack Kilo 版本中 Neutron 的新变化
  12. Spring 中 AOP 的实现原理——动态代理
  13. matlab 删除plot上的图,matlab删除部分图例
  14. java 地图坐标转换_百度地图坐标和高德地图坐标转换代码 Java实现
  15. 佐切的第四天学习分享
  16. 沧海一声笑(最好版)
  17. 安全邮箱是什么邮箱?怎么登录163邮箱?
  18. CAS和自旋到底是一个概念吗?
  19. Vue.js学习笔记—shop-bus:实战:利用计算属性、指令等知识开发购物车
  20. laravel5.0学习系列1之 路由

热门文章

  1. 使用navicat连接mysql出现提示10038错误的解决方法
  2. OpencvSharp的Mat类型数组传入c++的DLL
  3. dijkstra算法及其堆优化
  4. 【maven】maven是什么?maven安装及idea中使用maven
  5. 再见吧 buildSrc, 拥抱 Composing builds 提升 Android 编译速度
  6. Tensorflow2.0的简单GCN代码(使用cora数据集)
  7. 超低功耗LCD液晶显示驱动芯片(IC)-VKL128-稳定性好,超低工作电流,低休眠电流-技术开发资料
  8. Understanding parameters:理解参数(Parameter)
  9. UML时序图画法简介-sequenceDiagram
  10. 华科博士201万,西安交大本科生100万!华为「天才少年」校招薪资曝光