SVG支持动画。可以通过以下几种方法获得动画效果:

  • 使用SVG动画元素。SVG可以描述随时间变化的图形对象,使用不同的动画元素可以定义运动路径,淡入淡出效果和对象的膨胀、收缩、旋转和变换颜色。
  • 使用SVG DOM。SVG DOM兼容DOM1和DOM2,而SVG又定义了一套附加的DOM接口,支持脚本动画。通过这个方法可以获得各种动画效果。脚本语言中的定时器对象可以用来启动和控制动画。
  • SVG被设计为支持未来版本的SMIL(Sychronized Multimedia Integration Language)。SMIL将被模块化而与SVG及其它基于XML的语言连接,产生动画效果。

一、SVG中的动画元素

SVG中的动画元素有五个,它们都可以随着时间的变化而改变SVG元素的属性或样式值,如下所示:

  • <animate>:改变数值的属性或样式的值;
  • <set>:改变非数据值的属性或样式的值,如visibility属性等;
  • <animateMotion> 
    沿着某路径移动SVG元素获得动画效果, 该元素提供一种通过指定路径移动元素的简单方法。路径数据与路径元素的 d 属性相同,但用路径元素指定。也可以用 xlink:href 将它链接到 animateMotion 元素。起点和终点由 from 和 to 属性确定,并且可以通过将 rotate 值设为 auto 来设置对象垂直对齐于路径。(也可以将 rotate 属性设为 auto-reverse 以将这个方位改变 180 度。或者可以给定一个特定角度)。如动画和交互性所示:
    
    <animateMotion path="M0,300 S150,100 200,200 S400,400 500,0" dur="8s" repeatCount="indefinite" rotate="auto" />  
  • <animateColor>:改变某些元素与颜色有关的属性或样式的值;
<circle cx="250" cy="100" r="50" fill="red">
<animateColor attributeType="CSS" attributeName="fill" from="rgb(255,0,0)" to="rgb(0,0,255)" dur="8s" repeatCount="indefinite"/>
</circle> 
  • <animateTransform>:改变SVG元素进行坐标变换时候的动画效果;

    <rect x="333" y="49" width="50" height="50" fill="none" stroke="purple">
    <animateTransform attributeName="transform" attributeType="XML"
    type="scale" from="1" to="3" additive="sum" begin="3s" dur="6s" fill="freeze" />
    <animateTransform attributeName="transform" attributeType="XML"
    type="translate" from="0,0" to="-222,-45" additive="sum" begin="3s" dur="6s" fill="freeze" />
    </rect>
  • set:剩下的这个元素可以很容易地设置一个元素在指定时间段内的特殊属性
    <circle cx="250" cy="100" r="50" fill="red">
    <set attributeName="r" to="100" begin="1s" dur="5s" fill="remove" />
    </circle>

    attributeName="<attributeName>":批明所作用的SVG元素中哪个属性或样式需要产生动画效果。

attrbuteType="<XML|CSS|auto>":指明产生动画效果的属性或样式值是哪个命名空间定义的。“XML”表示“attributeName”的值是默认XML命名空间里定义的XML属性名;“CSS”表示“attributeName”的值是默认CSS属性的名称;“auto”是默认值,解析器解析时先在CSS属性列表中查找是否有匹配“attributeName”的属性名,然后再在XML的命名空间里找

1.与时间控制相关的常用属性

begin="<clock-time-value>|wallclock-sync-value|indefinite|eventName":定义动画的开始时刻。

  • a.时间偏移值,如3S表示3秒后开始播放动画(hh:mm:ss.xxxx)
  • b.现实世界中的时间,定义后要保证SVG文档要在这个时间之前打开
  • c.Endefinite:表示这个动画不会自动开始,需要使用动态脚本调用"beginElement()"方法或指向动画元素
  • d.eventName:表示在某个事件触发时开始播放动画。如begin="mousedown"
    • 1.dur="<clock-time-value>|indefinite":定义动画的持续时间
    • 2.end="<clock-time-value>|indefinite":定义动画的结束时间
    • 3.restart="always|whenNotactive|never":是否重播
    • 4.repeatCount:重复播放次数 indefinite表示无限重播
    • 5.repeatDur:定义动画播放总时间
    • 6.fil="freeze|remove":定义动画播放完毕后是停留在播放的终点还是回到起始位置

2.与过程控制相关的常用属性

from="<value>":定义该动画元素所作用的属性值在开始变化时的值

to="<value>":定义该动画元素所作用的属性值在结束变化时的值

by="<value>":定义该动画元素所作用的属性值每次变化的步长值

calcMode="discrete|linear|paced|spline":定义动画关键点直接过渡的插值计算方式

  • discrete表示不采用插值算法,动画是从一个关键点跳跃到另外一个关键点
  • linear表示采用线性插值算法,这是<animate>元素和<set>元素采用的默认插值算法
  • paced表示采用在埋单上均匀变化的方法来插值
  • spline表示采用三次贝塞尔曲线的方式来插值,需要"KeySplines"属性的配合

例子1:

<rect x="50" y="50" width="100" height="50">
<animate attributeType="XML" attributeName="x" from="50" to="300" dur="3s" begin="3s" restart="always" repeatCount="3" >
</animate>
</rect>

例子2:

<text x="0" y="0" font-size="37" visibility='hidden" stroke="black" stroke-width="2" >
<animateMotion path="M0,0 L50,50 L100,150" begin="1s" dur="5s" fill="freeze" rotate="auto"/>
</text>

例子3:

<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100,100)">
<text id="TextElement" x="0" y="0" style="font-family:Verdana;font-size:24; visibility:hidden"> It's SVG!
<set attributeName="visibility" attributeType="CSS" to="visible" begin="1s" dur="5s" fill="freeze" />
<animateMotion path="M 50 50 L 300 300" begin="1s" dur="5s" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="360" begin="1s" dur="15s" fill="freeze" repeatCount='indefinite'/>
<animateTransform attributeName="transform" attributeType="XML" type="scale" from="1" to="3" additive="sum" begin="1s" dur="5s" fill="freeze" />
</text>
</g>
</svg>

二、事件的脚本编制(DOM动画)

象 HTML 页面一样,可以设置 SVG 图像以捕获某些事件(如点击鼠标和滚动),并用它们启动脚本。在构建简单SVG 图像时,可以通过属性捕获这些事件。最常用的是onclick、onactivate、onmousedown、onmouseup、onmouseover、onmousemove、onmouseout、onload、onresize、onunload 和 onrepeat。

当这些事件之一被触发,就可以将事件对象本身提供给脚本,脚本反过来再用它确定哪个对象触发了该事件(也就是点击了什么对象)。然后脚本可以操纵那个对象的特性,如它的属性。 

这一示例回到了图案示例,但在此例中,当用户点击椭圆时,其填充由白色变为使用图案。

<?xml version="1.0"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<desc>Scripting the onclick event</desc>
<script type="text/ecmascript">
<![CDATA[
function hideReveal(evt) {
var imageTarget = evt.target;
var theFill = imageTarget.getAttribute("fill");
if (theFill == 'white')
imageTarget.setAttribute("fill", "url(#notes)");
else
imageTarget.setAttribute("fill", "white");
}
]]> </script>
<defs>
<pattern id="notes" x="0" y="0" width="50" height="75"
patternTransform="rotate(15)"
patternUnits="userSpaceOnUse">
<ellipse cx="10" cy="30" rx="10" ry="5"/>
<line x1="20" y1="30" x2="20" y2="0"
stroke-width="3" stroke="black"/>
<line x1="20" y1="0" x2="30" y2="5"
stroke-width="3" stroke="black"/>
</pattern>
</defs> <!-- Outline the drawing area with a blue line --> <rect x="1" y="1" width="350" height="200" fill="none" stroke="blue"/>
<ellipse onclick="hideReveal(evt)" cx="175" cy="100" rx="125" ry="60"
fill="url(#notes)" stroke="black" stroke-width="5"/> </svg>

三、基本的声明性 (SMIL) 动画

<?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="800px" height="800px" viewBox="0 0 800 800"
version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"> <!-- Note that this is required in order to use xlink in the <use> element. --> <!-- THIS EXAMPLE NOT SUPPORTED IN INTERNET EXPLORER --> <title>Simplest SVG Animation</title>
<desc>SVG declarative animation is used to rotate a square.</desc> <!-- Create a Cartesian coordinate system (with the y-axis flipped) for the animated square.
That is, place the origin at the center of the 800 x 800 SVG viewport. -->
<g transform="translate(400, 400)"> <!-- A 200 x 200 square with the upper left-hand corner at (-100, -100). This places the center
of the square at the origin (0, 0): -->
<rect x="-100" y="-100" width="200" height="200" rx="5" ry="5"
style=" fill: orange; stroke: black; stroke-width: 3; stroke-dasharray: 10, 5;">
<animateTransform
attributeType="xml"
attributeName="transform" type="rotate"
from="0" to="90"
begin="0" dur="5s"
fill="freeze"
/>
</rect> <line x1="-400" y1="0" x2="400" y2="0" style="stroke: black;" /> <!-- Represents the x-axis. --> <line x1="0" y1="-400" x2="0" y2="400" style="stroke: black;" /> <!-- Represents the y-axis (although up is negative and down is positive). --> </g>
</svg>

同样的效果用javascript来实现:

<!DOCTYPE html>
<html> <head>
<title>JavaScript SVG Animation</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/> <!-- Remove this line in production. -->
</head> <body>
<svg width="800px" height="800px" viewBox="0 0 800 800">
<g transform="translate(400, 400)"> <!-- Create a Cartesian coordinate system (with the y-axis flipped) for the animated square. That is, place the origin at the center of the 800 x 800 SVG viewport: --> <!-- A 200 x 200 square with the upper left-hand corner at (-100, -100). This places the center of the square
at the origin (0, 0): -->
<rect id="mySquare" x="-100" y="-100" width="200" height="200" rx="5" ry="5"
style=" fill: orange; stroke: black; stroke-width: 3; stroke-dasharray: 10, 5;" /> <!-- Represents the x-axis: -->
<line x1="-400" y1="0" x2="400" y2="0" style="stroke: black;" /> <!-- Represents the y-axis (although up is negative and down is positive): -->
<line x1="0" y1="-400" x2="0" y2="400" style="stroke: black;" /> </g>
</svg>
<script>
"use strict"; /* CONSTANTS */
var initialTheta = 0; // The initial rotation angle, in degrees.
var thetaDelta = 0.3; // The amount to rotate the square about every 16.7 milliseconds, in degrees.
var angularLimit = 90; // The maximum number of degrees to rotate the square.
var theSquare = document.getElementById("mySquare"); theSquare.currentTheta = initialTheta; // The initial rotation angle to use when the animation starts, stored in a custom property. var requestAnimationFrameID = requestAnimationFrame(doAnim); // Start the loop.
function doAnim() {
if (theSquare.currentTheta > angularLimit) {
cancelAnimationFrame(requestAnimationFrameID); // The square has rotated enough, instruct the browser to stop calling the doAnim() function.
return; // No point in continuing, bail now.
} theSquare.setAttribute("transform", "rotate(" + theSquare.currentTheta + ")"); // Rotate the square by a small amount.
theSquare.currentTheta += thetaDelta; // Increase the angle that the square will be rotated to, by a small amount.
requestAnimationFrameID = requestAnimationFrame(doAnim); // Call the doAnim() function about 60 times per second (60 FPS), or about once every 16.7 milliseconds until cancelAnimationFrame() is called.
}
</script>
</body>
</html>

用SVGDOM来实现:

<!DOCTYPE html>
<html> <head>
<title>JavaScript SVG Animation</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <!-- Remove this line in production. -->
</head> <body>
<svg id="svgElement" width="800px" height="800px" viewBox="0 0 800 800"> <!-- Give the svg element a name so that we can easily access it via JavaScript. --> <g transform="translate(400, 400)"> <!-- Create a Cartesian coordinate system (with the y-axis flipped) for the animated square. That is, place the origin at the center of the 800 x 800 SVG viewport: --> <!-- A 200 x 200 square with the upper left-hand corner at (-100, -100). This places the center of the square
at the origin (0, 0). Give the square a name so we can easily access it via JavaScript: -->
<rect id="mySquare" x="-100" y="-100" width="200" height="200" rx="5" ry="5"
style=" fill: orange; stroke: black; stroke-width: 3; stroke-dasharray: 10, 5;" /> <!-- Represents the x-axis: -->
<line x1="-400" y1="0" x2="400" y2="0" style="stroke: black;" /> <!-- Represents the y-axis (although up is negative and down is positive): -->
<line x1="0" y1="-400" x2="0" y2="400" style="stroke: black;" /> </g>
</svg>
<script>
"use strict"; /* CONSTANTS */
var initialTheta = 0; // The initial rotation angle, in degrees.
var thetaDelta = 0.3; // The amount to rotate the square about every 16.7 milliseconds, in degrees.
var angularLimit = 90; // The maximum number of degrees to rotate the square. /* GLOBALS */
var requestAnimationFrameID;
var mySquare = document.getElementById("mySquare");
var transformObject; mySquare.currentTheta = initialTheta; // The initial rotation angle to use when the animation starts, stored in a custom property.
transformObject = svgElement.createSVGTransform(); // Create a generic SVG transform object so as to gain access to its methods and properties, such as setRotate().
mySquare.transform.baseVal.appendItem(transformObject); // Append the transform object to the square object, now the square object has inherited all the transform object's goodness. requestAnimationFrameID = requestAnimationFrame(doAnim); // Start the animation loop.
function doAnim() {
var transformObject; if (mySquare.currentTheta > angularLimit) {
cancelAnimationFrame(requestAnimationFrameID); // Instruct the browser to stop calling requestAnimationFrame()'s callback.
return;
} mySquare.transform.baseVal.getItem(0).setRotate(mySquare.currentTheta, 0, 0); // Access the transform object (that was appended to mySquare in the init() function) and use its setRotate method to rotate the square about the point (0, 0) (which is at the center of the SVG viewport).
mySquare.currentTheta += thetaDelta; // Place this line here so that the square isn't over rotated on the last call to doAnim().
requestAnimationFrameID = requestAnimationFrame(doAnim); // Call the doAnim() function about every 60 times per second (i.e., 60 FPS).
}
</script>
</body>
</html>

参考:

HTML5的 2D SVG和SVG DOM的学习笔记(2)---SVG动画的更多相关文章

  1. HTML DOM(学习笔记二)

    嗯,在HTML DOM(学习笔记一)中简单描述了一下HTML DOM 是什么,这一篇将记录下来有关HTML DOM的内容! 1:DOM节点 首先,再来看一下HTML DOM的树状结构,如下图所示: 这 ...

  2. HTML DOM简易学习笔记

    文字版:https://github.com/songzhenhua/github/blob/master/HTML DOM简易学习笔记.txt 学习地址:http://www.w3school.co ...

  3. HTML5的 2D SVG和SVG DOM的学习笔记(1)

    (项目中要使用SVG,只好补充知识了) HTML体系中,最常用的绘制矢量图的技术是SVG和HTML5新增加的canvas元素.这两种技术都支持绘制矢量图和光栅图. 一.SVG概述 可缩放矢量图形(Sc ...

  4. 学习笔记:SVG和Canvas

    SVG SVG 与 Flash 类似,都是用于二维矢量图形,二者的区别在于,SVG 是一个 W3C 标准,基于 XML,是开放的.因为是 W3C 标准,SVG 与其他的 W3C 标准,比如 CSS.D ...

  5. DOM编程 学习笔记(一)

    PS:虽然自己JS基本语法算是掌握了,但是其实在JS掌握的只是远远还不够,网页上有太多好看的动态效果都是用JS 做出来的,自己也就仅仅会那么一两个动态的效果,学的只是皮毛...等有空的时候一定要好好的 ...

  6. HTML5与CSS3基础教程第八版学习笔记16-21章

    第十六章,表单 HTML5引入了新的表单元素.输入类型和属性,以及内置的对必填字段.电子邮件地址.URL以及定制模式验证. 元素: <input type="email"&g ...

  7. HTML5与CSS3基础教程第八版学习笔记11~15章

    第十一章,用CSS进行布局 开始布局注意事项 1.内容与显示分离 2.布局方法:固定宽度和响应式布局 固定宽度,整个页面和每一栏都有基于像素的宽度 响应式布局也称为流式页面,使用百分数定义宽度 3.浏 ...

  8. DOM扩展学习笔记

    对DOM的两个主要扩展是Selectors API(选择符API)和HTML5,还有一个不太瞩目的Element Traversal元素遍历规范为DOM添加了一些属性,另外还有一些专有扩展. 选择符A ...

  9. HTML DOM(学习笔记一)

    嗯,工作也有一段时间了,对编程的认识也深入了一些,以前认为HTML/CSS/JAVASCRIPT是比较简单的,看网上的教程就可以了,W3C是我学习这些知识常去的一个网站,非常感谢她让我学习到了更多的一 ...

随机推荐

  1. R数据实战vehicles--1

    新建项目vehicles-project 数据文件vehicles.csv与varlabels.txt放在项目文件中

  2. HTML5 Canvas arc()函数//////////////////////(转)

    HTML5 Canvas arc()函数   实例 创建一个圆形: var c=document.getElementById("myCanvas"); var ctx=c.get ...

  3. Java基本语法

    一:跨行 Java变量不能跨行,如:String na me = “张三"; 字符串不能跨行,如:String a = "xxxxxxxxxx yyyyyyyy"; 二: ...

  4. ef第一次启动较慢

    解决ef第一次启动较慢的问题: protected void Application_Start() { //禁用第一次ef查询对表__MigrationHistory的问题使用了ef的Code fi ...

  5. sysobjects中字段的含义

    --列名 数据类型 描述 name sysname --对象名. Id int --对象标识号. xtype ) --对象类型.可以是下列对象类型中的一种: C = CHECK --约束 D = -- ...

  6. ADO.NET 新特性之SqlBulkCopy

    在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还是进行不同数据源之间的迁移,都不是很方便.而 在.Net2.0中,SQLClient命名空间下增加了几个新类帮助我们 ...

  7. Mac平台上OpenCV开发环境搭建

    转载于:https://segmentfault.com/a/1190000000711132 linux 编译指定库.头文件的路径问题 http://blog.csdn.net/jiaweizou/ ...

  8. Python对整形数字进行加密和解密

    # -*- coding:utf-8 -*- __author__ = 'Ray' class Encryption: """整形数字简单的一个加密/解密算法" ...

  9. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  10. 分享 - 最初的JDBC操作步骤

    /* * 1. 注册 */ // 装载注册 SQLServer Driver Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDri ...