近期生活比较单一。
const 提升自己 = true;
while( 提升自己 ) {
写码
...
看书
...
思考
...
睡觉
}
既单一也充实,单一使我平静,充实使我保持向上的感觉,希望自己真难做到“持续学习,保持思考,不断进步”。
最近看到腾讯ISUX
团队的一篇博客《H5动效的常见制作手法》,里面简单介绍了现在H5开发中实现动画效果的几种方式(GIF,逐帧动画,css3,canvas,svg,video…),实际的内容不多,但对我多少有点启发意义,感兴趣的同学不妨看看。
作为一只前端小菜鸟,前端的各个细分领域都能吸引到我,于是看了上面的博客后,挑了最感兴趣的CSS3动画来学习。对于CSS3动画,我第一个想起的就是animate.css
,于是便有了这篇博客。
快速上手animate.css
animate.css
的主页简单明了,能演示各个动画的效果,目的也很简单,“just-add-water css animations
”。那天好奇去搜索了一下作者Daniel Eden
,真是酷到不行。
不多说,直接上学习资料:
估计读完github里面的README.md
之后就不用往下看了吧,对于animate.css
的用法早已了然于心,如果你还有兴趣,想看看我这个无聊的博主能写些什么东西,希望不会让你失望。
一,静态使用动画(很绕吧…)
- 引用
animate.css
- 给需要动画的元素添加
class
<!-- animated是必须添加的;bounce是动画效果;infinite从语义来看也秒懂,无限循环,不添加infinite默认播放一次 -->
<div class="animated bounce infinite">动画</div>
- 刷新页面就能看到动画这两个字在上下蹦。done,静态使用就这么简单
总结一下场景和优缺点吧,优点是简单呀,添加个类名就一劳永逸了,一行js代码都不用写,缺点是不能人为控制开始和停止。我能想到的场景:
①loading
动画
②新开页面某些元素动一次,能吸引用户注意(如注册按钮等)
二,动态使用
掌握了上述用法之后,动态使用也不过小菜一碟。基本思路如下:
给动画对象添加类,然后监听动画结束事件,一旦监听到动画结束,立即移除前面添加的类。
这样一来,想什么时候开始和结束动画都随你了。对于这种用法(也是实际开发中最多的用法),官方给出了jQuery的封装:
//扩展$对象,添加方法animateCss
$.fn.extend({
animateCss: function (animationName) {
var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
$(this).addClass('animated ' + animationName).one(animationEnd, function() {
$(this).removeClass('animated ' + animationName);
});
}
});
//使用示例:
$('#yourElement').animateCss('bounce');
因为手上有个小项目没用jQuery
这么高大上的库,于是自己写了个js原生的实现,也扩展了一些功能:
//animate("选择器","动画","次数","时延")
function animate(seletor, animation_name, count, delay) {
var target = document.querySelectorAll(seletor)
var timer = null;
timer = setInterval( function() {
target.forEach( function(x) {
x.className += " animated " + animation_name;
x.addEventListener("animationend", function(){
x.className = x.className.replace(" animated " + animation_name, "");
});
} )
count --;
if( count <= 0 ) {
clearInterval( timer );
}
}, delay)
}
//使用示例
animate('.haha', "bounce", 2, 1000);
上面的代码也就是个半成品:
- 只监听了”
animationend
”事件,兼容性不好(可多次调用addEventListener
监听其他事件); - 先延时,再执行(将回调函数封装一下,先调用回调函数一次,再进入间隔循环)
源码解析
源码只有一份animate.css
,相对简单,下面主要说说三个关键类。
一,animated
设置了动画时长和动画执行前后元素应该怎样应用样式(animation-fill-mode
)
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
二,infinite
设置了动画次数(无限次)
.infinite {
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
三,动画类名(如:bounce
)
设置使用的动画,及一些动画的初始化属性。
.bounce {
-webkit-animation-name: bounce;
animation-name: bounce;
-webkit-transform-origin: center bottom;
transform-origin: center bottom;
}
@keyframes bounce {
from, 20%, 53%, 80%, to {
-webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
40%, 43% {
-webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
-webkit-transform: translate3d(0, -30px, 0);
transform: translate3d(0, -30px, 0);
}
70% {
-webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
-webkit-transform: translate3d(0, -15px, 0);
transform: translate3d(0, -15px, 0);
}
90% {
-webkit-transform: translate3d(0,-4px,0);
transform: translate3d(0,-4px,0);
}
}
总的来说实现的原理比较简单,业务组织也很明确,就是三个类,比较有意思的是去研究各个动画的keyframes
是怎样的,很有意思(细节远比我想象的要多),例如上面那个bounce
动画,从关键帧就能看出很多细节,随意蹦两下那么粗糙。
自定义选项
这个放在最后是因为看了源码之后很自然就无师自通懂得怎么自定义了,例如想用css
来控制动画次数等。
#yourElement {
-vendor-animation-duration: 3s;
-vendor-animation-delay: 2s;
-vendor-animation-iteration-count: infinite;
}
else
内联元素(如a标签)不支持bounce动画。
动画学习的最大感悟是,好想去学动画设计呀,好动感。