CSS3属性animation-play-state控制动画运⾏或暂停的技巧anim ation-p lay-s tate介绍
animation-play-state 属性规定动画正在运⾏还是暂停。
div{
animation-play-state:paused;
-webkit-animation-play-state:paused; /* Safari 和 Chrome */
}
浏览器⽀持:
Internet Explorer 10、Firefox 以及 Opera ⽀持 animation-play-state 属性。
Safari 和 Chrome ⽀持替代的 -webkit-animation-play-state 属性。
注释:Internet Explorer 9 以及更早的版本不⽀持 animation-play-state 属性。
语法:animation-play-state: paused|running;
paused 规定动画已暂停。
running 规定动画正在播放。
下⾯讲解⼀下animation-play-state的使⽤技巧。
注:⽰例代码的私有前缀均省略,⼤家⾃⾏脑补
使⽤anim ation-p lay-s tate控制每屏动画播放
1. 类名activ e与动画触发
⾸先,使⽤active触发每⼀屏的动画,⼏乎已经约定俗成,应该也建议成为默认的⾏业规范。
⼀般做法是,当对应⼀屏内容进⼊的时候,使⽤JS给容器添加类名active:
container.classList.add("active");
如果你做的动画逼格较⾼,希望每次浏览这⼀屏内容的时候,动画都⾛⼀遍,可以使⽤reflow重新触发⼀下animation:
ve("active");
container.offsetWidth = container.offsetWidth;
container.classList.add("active");
2. 类名activ e与动画控制技巧
如何具体控制动画的播放呢?我们通常第⼀反应是使⽤下⾯的⽅法实现,动画的完整CSS代码在active状态下呈现,如:
.element1 { /* 尺⼨与定位 */ }
.element2 { /* 尺⼨与定位 */ }
.element3 { /* 尺⼨与定位 */ }
...
.active .element1 { animate: name1 1s; }
.active .element2 { animate: name2 1s; }
.active .element3 { animate: name2 1s; }
...
从实现和功能上将,上⾯⽅法是很不错的,通俗易懂,不易犯错。不过我个⼈更喜欢使⽤配合CSS3的animation-play-state属性对每屏动画进⾏控制,实现如下:
动画相关CSS代码直接写在元素上:
.element1 { /* 尺⼨与定位 */ animate: name1 1s; }
.element2 { /* 尺⼨与定位 */ animate: name2 1s; }
.element3 { /* 尺⼨与定位 */ animate: name3 1s; }
...
创建⼀个类名,如.animate,凡是使⽤到了animation动画的元素都添加这个类名;如下CSS代码:
.animate {
animation-play-state: paused;
}
.active .animate {
animation-play-state: running;
}
之所以个⼈更喜欢后⾯的⽅法,是因为有⼀种“⽆侵⼊”的感觉,代码层次清晰,控制关系明确。有利于后期的维护与扩展。
然⽽,使⽤animation-play-state还是有些需要注意的,对于IE10/IE11浏览器,animation-play-state是不能简写的。如:
只会让整个CSS声明挂掉的!如下写法⽀持:
.element {
animate: shake 4s 2s both infinite;
animation-play-state: paused;
}
有⼈可能要奇怪了,怎么突然IE浏览器乱⼊了?⾸先,我们不能⽆视主流⼿机之Windows Phone. 其次,帅⽓的翻屏动画并不是移动端专有,桌⾯端也适⽤。稍稍⽤⼒,桌⾯移动全适配,何乐⽽不为!
不同状态下的连续动画
有时候,动画可能不是⼀波流,分状态。
例如,我们的⼩⽕箭,先是淡出动画,然后⽆限上下悬浮。怎么实现呢?
关键点就是动画分解与延时。
据我所知,没办法只使⽤⼀个keyframes关键帧声明就实现这个效果,因为,这⾥有动画状态的变化:⼀个只执⾏⼀次的动画和⼀个⽆限循环动画。
怎么办?我们可以将动画分解,写2个animation keyframes动画关键帧描述。
@keyframes fadeIn { /* ... */ }
@keyframes float { /* ... */ }
然后,再分别应⽤这些关键帧动画。如何应⽤呢?有2个⼩技巧:
1. 逗号与多animation动画值
如下:
div class="element">⼩⽕箭</div>
.element { animation: fadeIn 1s, float .5s 1s infinite; }  /* 我淡出, 需要1秒;我1秒后开始⽆限漂浮 */
其中float .5s 1s infinite这⾥的1s就是⽆限漂浮动画执⾏延迟的时间,于是,两个动画完美配合,感觉就像是⼀个动画。实际上,就是⼀个动画,所有CSS3 animation动画⾛同⼀个UI线程,这也是为何推荐使⽤CSS实现动画效果的原因。
此写法没有兼容性问题,⼤家可以开开⼼⼼地使⽤。
2. 标签嵌套与独⽴动画
我们还可以通过嵌套标签的形式实现连续动画,例如:
<div class="element-wrap"><div class="element">⼩⽕箭</div></div>
.element-wrap { animation: fadeIn 1s; }          /* 我淡出, 需要1秒 */
.element { animation: float .5s 1s infinite; }  /* 我1秒后开始⽆限漂浮 */
有⼈可能会奇怪了。animation本⾝就⽀持多动画并⾏,你还搞个标签嵌套,没有任何使⽤的理由啊!没错,单纯看我们这个例⼦,确实是这样。但是:
① 提取公⽤动画
这类多屏动画是有N多元素同时执⾏不同的动画。⽐⽅说,⽕箭是淡出,然后上下漂浮;⽕箭的⽕焰是淡出,然后⼤⼩变化;⿊洞是淡出,然后左右随波。你如何实现?
如果纯粹借助animation语法,应该是:
.element1 { animation: fadeIn 1s, float .5s 1s infinite; }  /* 我淡出, 需要1秒;我1秒后开始⽆限漂浮 */
.element2 { animation: fadeIn 1s, size .5s 1s infinite; }  /* 我淡出, 需要1秒;我1秒后开始⼤⼩变化 */
.element3 { animation: fadeIn 1s, move .5s 1s infinite; }  /* 我淡出, 需要1秒;我1秒后开始左右移动 */
可以看到,淡出是公⽤的动画效果,我们可以借助嵌套标签,实现公⽤语法的合并,⽅⾯后期维护:
.element-wrap { animation: fadeIn 1s; }          /* ⼤家都1秒淡出 */
.element1 { animation: float .5s 1s infinite; }  /* 我1秒后⽆限漂浮 */
.element2 { animation: size .5s 1s infinite; }  /* 我1秒后忽⼤忽⼩ */
.element3 { animation: move .5s 1s infinite; }  /* 我1秒后左右移动 */
②避免变换冲突
有个元素动画是边360度旋转、边放⼤(从0放⼤到100%),像这种具有典型特征的动画我们显然要独⽴提取与公⽤的:
@keyframes spin { /* transform: */ }
@keyframes zoomIn { /* transform: */ }
好了,现在问题来了,边放⼤边旋转:
.element { animation: spin 1s, zoomIn 1s; }  /* 旋转:啊,完蛋啦,我被放⼤覆盖啦! */
由于都是使⽤transform, 发⽣了残忍的覆盖。当然,有好事的⼈会说,你使⽤zoom不就好了!确实,如果只是移动端,使⽤zoom确实棒棒哒!但是,我们这个企业活动,PC是主战场,因此,FireFox浏览器(FF不识zoom)是不能⽆视的。
怎么办?重新建⼀个名为spinZoomIn的动画关键帧描述还是?
对啊,你直接外⾯套⼀层标签不就万事⼤吉了
.element-wrap { animation: spin 1s; }  /* 我转转转 */
.element { animation: zoomIn 1s; }      /* 我⼤⼤⼤ */
⽆侵⼊定位和居中定位准则
1. 这⾥的“⽆侵⼊定位”指不受anim ation影响的元素定位,包含两部分:⼀是不使⽤ke yf r am e s关键帧决定初始位置;⼆是不要使⽤ke yf r am e s中出现的属性定位。
①. 不使⽤keyframes决定初始位置
应该都知道,C S S3 animation的fill-mode可以决定元素动画结束前后的位置,也就是也具有定位的作
⽤。此时,可能就会有⼩伙伴,故作聪明,利⽤animation keyframes 0% {}或form {}去做定位,貌似,还省了写代码。看上去很赞,实际上狭隘了,这对于对animation⽀持不佳或不⽀持的浏览器实际上是不友好的,例如Android2.3不⽀持animation-fill-mode, IE6-IE9不⽀持CSS3 animation,于是乎,当遭遇这些浏览器的时候,页⾯动画元素的布局实际上是毁掉的。所以,这些动画元素定位的时候,需要使⽤“⽆侵⼊定位”,也就是,就算页⾯没有animation, 我也是个“标致⼈⼉”。
②. 不使⽤keyframes中出现的属性定位
举个例⼦,有个球,正好定位在模块的中⼼,同时有个⽆限旋转效果。使⽤transform: translate(-50%,-50%)居中定位再合适不过了,不⽤我⼼⾥难受,于是,使⽤了transform定位。此时,冲突发⽣,旋转动画也是需要transform变换的。
@keyframes spin {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
要么使⽤业界约定俗成spin覆盖,要么另起炉灶没法重⽤:
@keyframes spin-trans {
0% { transform: rotate(0) translate(-50%,-50%); }
100% { transform: rotate(360deg) translate(-50%,-50%); }
}
显然,都是不合适的。建议使⽤传统left/top/margin进⾏定位,与transform变换动画“⽆侵⼊”。
2. 这⾥的“居中定位准则”包含两部分:⼀是元素定位在容器中间位置;⼆是元素的定位⽅式为居中定位。
①. 元素定位在容器中间
容器以及容器内的动画元素可以看成是⼀个动画模块,为了这个模块可以轻松驾驭⽔平布局和垂直局部,⾥⾯的动画元素形成的整体⼀定要在容器的中间,不要被设计稿或周围环境影响。
position标签属性
②. 定位⽅式为居中定位
所谓“居中定位”是相对“传统定位”⽽⾔的。Web页⾯中的模块、⽂字什么的默认都是相对于左上⾓堆砌
的,所以,很⾃然地,我们在重构页⾯,做布局,写交互效果的时候,也都是相对左上⾓定位。活⽤元素本⾝的定位特性,这是很赞的也推荐这么做!但是,如果你和多元素CSS动画打交道,可能就需要改变下惯性思维了,很重要的⼀点就是“从以左上⾓为参考点变成以中⼼点为参考点”。
我们在实现多元素动画效果时候,会出现两类⾓⾊:⼀是容器;⼆是容器⾥⾯诸多动画元素。
其中,对于容器元素,尤其在做移动端产品时候,我们很⾃然会让其居中定位:
.container {
position: absolute; left: 50%; top: 50%;
transform: translate3d(-50%, -50%, 0);
}
左上⾓定位(或右上⾓定位):
.example {
position: absolute; left: 100px; top: 100px;
}
中⼼点定位+ margin偏移:
.example {
position: absolute; left: 50%; top: 50%;
margin-left: -100px; margin-top: -100px;
}
在《》中⽤到了animation-play-state属性,有兴趣的可以查看下。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。