为什么80%的码农都做不了架构师?>>>
1. attributeName =
要变化的元素属性名称,① 可以是元素直接暴露的属性,例如,对于本文反复出现的「马」对应的text
元素上的x
, y
或者font-size
; ② 可以是CSS属性。例如,透明度opacity
.
2. attributeType = “CSS | XML | auto”attributeType
支持三个固定参数,CSS
/XML
/auto
. 用来表明attributeName
属性值的列表。x
, y
以及transform
就属于XML
, opacity
就属于CSS
. auto
为默认值,自动判别的意思(实际上是先当成CSS处理,如果发现不认识,直接XML类别处理)。因此,如果你不确信某属性是XML类别还是CSS类别的时候,我的建议是不设置attributeType
值,直接让浏览器自己去判断,几乎无差错。
不知大家有没有和我一样的疑问:“既然浏览器酱可以自己判断属性类别,那这个属性还有什么意义吗?”我琢磨着,可能某些属性,XML能其作用,CSS也能其作用,例如font-size
, 此时就需要明确下归属。
3. from, to, by, values
上面4个属性是一个家族的,是最具哲理的一个家族。他们解决的是非常有哲理的问题:你从哪里来?要到哪里去?……
from = “
“ 动画的起始值。
to = “
“ 指定动画的结束值。
by = “
“ 动画的相对变化值。
values = “
用分号分隔的一个或多个值,可以看出是动画的多个关键值点。
from
, to
, by
, values
虽然属于一个家族,但是相互之间还是有制约关系的。有以下一些规则:
a. 如果动画的起始值与元素的默认值是一样的,from
参数可以省略。
b. (不考虑values
)to
,by
两个参数至少需要有一个出现。否则动画效果没有。to
表示绝对值,by
表示相对值。拿位移距离,如果from
是100
, to
值为160
则表示移动到160
这个位置,但是,如果by
值是160
,则表示移动到100+160=260
这个位置。
c. 如果to
,by
同时出现,则by
打酱油,只识别to
.
d. 如果to
,by
,values
都没设置,自然没动画效果。如果任意(包括from
)一个属性的值不合法,规范上说是没有动画效果。但是,据我测试,FireFox浏览器确实如此,但是Chrome特意做了写容错处理。例如,本来是数值的属性,写了个诸如a
这个不合法的值,其会当作0
来处理,动画效果依然存在。
e. values
可以是一个值或多值。根据我在Chrome浏览器下的测试,是一个值的时候是没有动画效果。多值时候有动画效果。当values
值设置并能识别时候,from
, to
, by
的值都会被忽略。那values
属性是干什么的呢?别看名字挺大众的,其还是有些功力的。我们实现动画,不可能就是单纯的从a位置到b位置,有时候,需要去c位置过渡下。此时,实际上有3个动画关键点。而from
, to
/by
只能驾驭两个,此时就是values
大显身手的时候了!例如下面这个聪明的马儿来回跑的效果(没有效果点这里horse-values.svg):
总结下,也就是from-to
动画、from-by
动画、to
动画、by
动画以及values
动画。
4. begin, endbegin
指动画开始的时间,看上去很简单。设个时间,延迟嘛~~实际上非也非也,上面出现的beigin="3s"
只是最简单最基本的表示。
begin
的定义是分号分隔的一组值。看到没?是一组值,单值只是其中的情况之一。例如,beigin="3s;5s"
表示的是3s
之后动画走一下,6s
时候动画再走一下(如果之前动画没走完,会立即停止从头开始)。所以,如果一次动画时间为3s
, 即dur="3s"
,同时没有repeatCount
属性时候,我们可以看到动画似乎连续执行了2
次。
时间值
既然这里提到了时间,就顺势讲简单一下SVG animation中的时间表示(也适用于dur
, end
属性)。常见单位有 "h"
|"min"
|"s"
|"ms"
时间值支持的格式和规则相当复杂,例如我我规范上看到这个:1997-07-16T19:20:30.45+01:00
. 以及洋洋洒洒N多看不懂的示意。尼玛,这个要通透我周末钓鱼时间都没了,关键是没有必要。所以,我们还是了解下最常见的基本使用。
上面的单位含义都是英文单位的缩写。例如h
表示小时(hour).
时间值支持小数写法,因此,90s
我们也可以使用1.5miu
表示。时间值还支持hh:mm:ss
这种写法,因此,90s
我们也可以使用01:30
表示。
还有一点,十进制的小数值是秒的浮点定义。什么意思呢?就是如果begin="1.5"
没有单位,这里的小数点表示秒,也就是1.5s
的意思。所以,上面N次出现的beigin="3s"
也可以简写作beigin="3"
. 我测了下,FireFox和Chrome浏览器都是支持的。
begin
的单值除了普通value,还有下面这些类别的value:offset-value
| syncbase-value
| event-value
| repeat-value
| accessKey-value
| media-marker-value
| wallclock-sync-value
| "indefinite"
① offset-value
表示偏移值,数值前面有+
或-
. 应该指相对于documentdocument的begin
值而言。
② syncbase-value
基于同步确定的值。语法为:[元素的id].begin/end +/- 时间值
. 就是说借用其他元素的begin值再加加减减,这个可以准确实现两个独立元素的动画级联效果。OK,看完下面的例子一定会豁然开朗,对于上面的offset-value
也会有一定的认知。
这样的代码:
于是,实现了一个马儿折线跑的效果,先横向移动,再无缝纵向移动(没有效果点这里horse-animate-x-y.svg)。
如果您发现没有效果,可以狠狠地点击这里直接在浏览器中显示SVG:horse-animate-x-y.svg
可以看到,后面attributeName
为y
的元素的begin
值是x.end
. x.end
中的x
就是上面一个animate
元素的id
值,而end
是动画元素都有的一个属性,动画结束的时间。因此,begin="x.end"
意思就是,当id
为x
的元素动画结束的时候,我执行动画。非常类似于PowerPoint动画的“上一个动画之后”的选项。
当然,我们还可以增加一些偏移值,例如begin="x.end-1s"
, 就表示id
为x
的元素动画结束前一秒开始纵向移动。
③ event-value
这个表示与事件相关联的值。类似于PowerPoint动画的“点击执行该动画”。语法是:[元素的id].[事件类型] +/- 时间值
. 举个例子,点击下图的圆圈圈,马儿它就会自己跑!
代码的关键点就是上面红色高亮的begin="circle.click"
, 其中circle
为circle
元素(黑色圆)的id
, click
表示点击事件。含义一目了然,如果你想点击圆圈圈2秒钟后马儿才跑,很简单,偏移时间加上就可以了——begin="circle.click+2s"
.
主要注意的是,这类与事件关联的SVG需要内联在页面中,否则click
什么的都是徒劳。
④ repeat-value
指重复多少次之后干嘛干嘛。语法为:[元素的id].repeat(整数) +/- 时间值
. 举个例子,下面这个马儿会在水平运动2次之后,斜向运动(没有效果点这里horse-repeat-value.svg)……
SVG代码如下:
begin="x.repeat(2)"
指id
为x
的元素的动画重复2
次后执行~~
⑤ accessKey-value
定义快捷键。即按下某个按键动画开始。语法为:accessKey(" character ")
. character
表示快捷键所在的字符,举个例子,按下s
键动画走起。SVG代码如下:
SVG实时显示如下:
按下键盘上的字母"s"
, 理论上动画就会执行。但是,据我测试,我的Chrome浏览器(版本36)上是没有效果的,FireFox浏览器效果杠杠的!所以,如果您的浏览器没有效果,但是手上有火狐,可以复制下面这个地址去FireFox浏览器下感受下:http://www.zhangxinxu.com/study/201408/horse-accesskey-value.svg
⑥ wallclock-sync-value
指真实世界的时钟时间定义。时间语法是基于在ISO8601中定义的语法。例如上面提到的1997-07-16T19:20:30.45+01:00
这个让人呵呵呵的时间表示。
⑦ "indefinite"
就是这个字符串值,表示“无限等待”。据说需要beginElement()
方法触发或者指向该动画元素的超链接(SVG中的a
元素)。
下面代码是beginElement()
方法触发的例子:
var animate = document.getElementsByTagName("animate")[0];
if (animate) {
document.getElementById("svg").onclick = function() { animate.beginElement();
};
}
上面是HTML代码,下面是JS代码。意思很简单,点击我们的svg
, 触发animate
元素的beginElement()
方法,前提是begin="indefinite"
. 由于牵扯JS, 文章页拘谨了,您可以狠狠地点击这里:beginElement()方法触发SVG动画demo
超链接触发的例子参见下面:
SVG代码如下:
从上面代码可以看出,动画触发条件很简单,只要a
元素的xlink:href
指向的我们的动画元素就可以了。
如果上面SVG没效果,可以试试点击这里直接浏览器中访问:horse-begin-link.svg
最后,搞一段规范上出现的一段文字:
If no begin is specified, the default value is “0” – the animation begins when the document begins. If there is any error in the argument value syntax for begin, the default value for begin will be used.
意思是,没有begin
或者begin
参数解析异常,都当作0
处理。
说到现在基本上都是begin
属性,实际上end
与begin
除了名字和字面含义不一样,其值的种类与表意都是一模一样的,我这里就不重复啰嗦了。
5. durdur
属性值比begin
简单了好几层楼,就后面两种:常规时间值 | "indefinite"
.
“常规时间值”就是3s
之类的正常值;"indefinite"
指事件无限。试想下,动画时间无限,实际上就是动画压根不执行的意思。因此,设置为"indefinite"
跟没有dur
是一个意思,与dur
解析异常一个意思。
6. calcMode, keyTimes, keySplines
这几个参数是控制动画先快还是先慢类似这样作用的。
calcMode
属性支持4个值:discrete
| linear
| paced
| spline
. 中文意思分别是:“离散”|“线性”|“踏步”|“样条”。
discrete
from
值直接跳到to
值。linear
animateMotion元素以外元素的
calcMode
默认值。动画从头到尾的速率都是一致的。paced
通过插值让动画的变化步调平稳均匀。仅支持线性数值区域内的值,这样点之间“距离”的概念才能被计算(如
position
,width
,height
等)。如果”paced
“指定,任何keyTimes
或keySplines
值都会打酱油。spline
插值定义贝塞尔曲线。
spline
点的定义在keyTimes
属性中,每个时间间隔控制点由keySplines
定义。
keyTimes = “”
跟上面提到的
类似,都是分号分隔一组值。keyTimes
总名字上看是关键时间点的意思,大致就是这个意思。前面提到过values
也是多值,这里有一些约定的规则:首先,keyTimes
值的数目要和values
一致,如果是from/to/by
动画,keyTimes
就必须有两个值。然后对于linear
和spline
动画,第一个数字要是0
, 最后一个是1
。 最后,每个连续的时间值必须比它前面的值大或者相等。
paced
模式下,keyTimes
会被忽略;keyTimes
定义错误,也会被忽略;dur
为indefinite
也会被忽略。
keySplines = “”
keySplines
表示的是与keyTimes
相关联的一组贝塞尔控制点(默认0 0 1 1
)。每个控制点使用4个浮点值表示:x1 y1 x2 y2
. 只有模式是spline
时候这个参数才有用,也是分号分隔,值范围0~1
,总是比keyTimes
少一个值。
如果keySplines
值不合法或个数不对,是没有动画效果的。
叨叨这么多,规范的术语还真是拗口,不急,我们先感受例子,然后再给大家通俗解释:
如下4个SVG,只展示重要部分代码:
其效果为……您可以狠狠地点击这里:calcMode, keyTimes, keySplines属性demo
可以看到到4匹马上半途中你追我赶的经常场面:
拿最后一个SVG说事吧,实际上就是values
, keyTimes
, keySplines
三个人之间事情。values
确定动画的关键位置,keyTimes
确定到这个关键点需要的时间,keySplines
确定的是每个时间点段之间的贝塞尔曲线,也就是具体的缓动表现。我们平时CSS3写的transition
动画效果,也是这么回事,这是values
值就两个,所以,keyTimes
只能是0;1
, 贝塞尔曲线就只有一个,要不ease
, 要不linear
等。
7. repeatCount, repeatDurrepeatCount
表示动画执行次数,可以是合法数值或者”indefinite
“(动画循环到电脑死机)。
repeatDur
定义重复动画的总时间。可以是普通时间值或者”indefinite
(”动画循环到电脑死机)。
例如这个:
动画只玩执行完整3
个 +
一个1/3
个动画。因为repeat总时间就10s
而已。
8. fillfill
表示动画间隙的填充方式。支持参数有:freeze
| remove
. 其中remove
是默认值,表示动画结束直接回到开始的地方。freeze
“冻结”表示动画结束后像是被冻住了,元素保持了动画结束之后的状态。
9. accumulate, additiveaccumulate
是累积的意思。支持参数有:none
| sum
. 默认值是none
. 如果值是sum
表示动画结束时候的位置作为下次动画的起始位置。
additive
控制动画是否附加。支持参数有:replace
| sum
. 默认值是replace
. 如果值是sum
表示动画的基础知识会附加到其他低优先级的动画上,
举两个例子,下面是例子1:
这里轮到第二个动画的时候,路径是从第一个动画路径结束地方开始的,于是,3个动画完美无缝连接起来了。
例子2:
;
这里,两个动画同时都是transform
,都要使用一个type
属性,好在这个例子additive="sum"
是累加的而不是replace
替换。于是,我们就可以是实现一边旋转一边放大的效果(没有效果点这里horse-animate-sum.svg)。
10. restartrestart
这个属性诞生的背景如下:很多动画呢,其触发可能与事件相关,例如,点击某圆圈,马儿就跑。而且,似乎没点一次,马儿就跑一下。现在,存在这种情况,希望马儿只跑一次,之后在点击就没有反应。这种需求的出现迫使restart
参数的出现。支持的参数有:always
| whenNotActive
| never
.
always
是默认值,表示总是,也就是点一次圈圈,马儿跑一下。whenNotActive
表示动画正在进行的时候,是不能重启动画的。never
表示动画是一波流。
很好理解的参数,就不举例了。
11. min, max
min/max
表示动画执行最短和最长时间。支持参数为时间值和"media"
(媒介元素有效), max
还支持indefinite
.
12. ...
等其他遗漏参数。