CSS3 Animation
一、CSS3 动画的属性和描述
(1) 规定动画的名称、周期
/* animateTimer默认值为0,动画不会被执行。 */
div {
animation: animateName animateTimer;
}
(2) 描述动画
/* from...to... <=> 0%...100% */
@keyframes animateName {
from {...}
to {...}
}
这里就不一一列举了,可以查看w3cschool css3教程介绍还是蛮详细的,但是缺少部分比较使用的事件讲解,这个就需要查阅一下博客了。
二、CSS3 动画的三个事件
(1)开始事件: animationStart
(2)结束事件: animationEnd
(3)重复运动事件: animationIteration
当然,css3动画的支持还不是很全面,之前是webkit内核的浏览器支持比较好,以下是特定内核的前缀。
var ANIMATION_EVENT_PREFIX = ['Moz', 'webkit', 'ms', 'O'];
我表示不是很好用,也许是我用的不对吧,最后还是采用定时器来解决一些问题的。其实CSS3动画还是挺酷的,下次阅读一下官方文档,看是怎么实现的。
三、动动手,找下感觉
其实之前做动画,是采用JQuery的一些动画API和自定义动画来做。后来也用了QWrap来做,可能是因为类似的框架主要针对PC端,所以在移动端的性能自然就不是那么理想,不过iphone的性能还是不错的,做出来的效果还不算很卡,Android 4.x还没测试过。
当然,你也可以采用一些流行的移动端的库,比如:zeptojs等等,很少做移动端,就不多说了,怕误导人。
接下来用一个实际的例子,熟悉一下CSS3动画的API和使用的感觉。
功能描述:主要是一个菜单,点击展示/隐藏列表内容,是一个比较经典的交互。
(1)HTML部分,简单的一个例子结构。
<div id="mininav">
<div class="nav">
<button id="JS-menu">菜单</button>
<ul id="JS-items" data-animate="hide" class="items">
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
<li class="item"><a href="http://www.so.com/">360搜索</a></li>
</ul>
</div>
</div>
(2)CSS部分,看到多,其实就是为了处理前缀那些,还是不复杂。
body, ul, li { margin: 0; padding: 0; }
#mininav .items { list-style: none; overflow: hidden; display: none; }
#mininav .item { width: 100%; height: 30px; line-height: 30px; background: #ddd; margin-top: 5px; }
#mininav .item a { display: block; width: 100%; height: 30px; }
#mininav .show { animation: show 1s; -moz-animation: show 1s; -webkit-animation: show 1s; -o-animation: show 1s; }
#mininav .hide { animation: hide 1s; -moz-animation: hide 1s; -webkit-animation: hide 1s; -o-animation: hide 1s; }
@keyframes show { from { height: 0; } to { height: 245px; } }
@-moz-keyframes show { from { height: 0; } to { height: 245px; } }
@-webkit-keyframes show { from { height: 0; } to { height: 245px; } }
@-o-keyframes show { from { height: 0; } to { height: 245px; } }
@keyframes hide { from { height: 245px; } to { height: 0; } }
@-moz-keyframes hide { from { height: 245px; } to { height: 0; } }
@-webkit-keyframes hide { from { height: 245px; } to { height: 0; } }
@-o-keyframes hide { from { height: 245px; } to { height: 0; } }
(3)JS部分,主要处理动态交互的效果,因为有按钮事件嘛。以下代码只是测试用,有些并未封装成库,如果实际中要用,可以采用jquery或者其他什么库,就没那么麻烦了。
核心代码:
var menu = document.getElementById('JS-menu'),
nav = document.getElementById('JS-items');
/* 菜单的状态 */
var STATUS = {
show: 'show',
hide: 'hide'
};
/* 定时器索引 */
var timer = null;
addEvent(menu, 'click', function (e) {
if(nav.getAttribute('data-animate') == STATUS.hide) {
clearTimeout(timer); //防止连续不断的点击
nav.style.display = 'block';
removeClass(nav, STATUS.hide);
addClass(nav, STATUS.show);
nav.setAttribute('data-animate', STATUS.show);
} else {
timer = setTimeout(function () {
nav.style.display = 'none';
}, 1000);
removeClass(nav, STATUS.show);
addClass(nav, STATUS.hide);
nav.setAttribute('data-animate', STATUS.hide);
}
}, false);
上面主要就是点击的一个交替,使用定时器是因为自带的动画结束事件未使用成功,之后单独学习一下,总感觉哪儿不对。定时器的时间必须和动画时间一致,动画也有一些参数可以控制效果,可以查看相应API,我使用的默认效果。
以下是完整JS代码:
(function () {
var menu = document.getElementById('JS-menu'),
nav = document.getElementById('JS-items');
function addEvent(obj, type, fun, isBubble) {
if(obj.addEventListener) {
obj.addEventListener(type, fun, isBubble);
} else {
obj.attachEvent('on' + type, fun);
}
}
function hasClass(obj, clazz) {
return obj.className.match(new RegExp('(\\s|^)' + clazz + '(\\s|$)'));
}
//添加指定class,如果你直接className=papapa,值会被覆盖,所以需要累加
function addClass(obj, clazz) {
if(!hasClass(obj, clazz)) {
obj.className += ' ' + clazz;
}
}
//去除指定class,如果有兴趣可以做一个class交替操作
function removeClass(obj, clazz) {
if (hasClass(obj, clazz)) {
var reg = new RegExp('(\\s|^)' + clazz + '(\\s|$)');
obj.className = obj.className.replace(reg, '');
}
}
/* 菜单的状态 */
var STATUS = {
show: 'show',
hide: 'hide'
};
/* 定时器索引 */
var timer = null;
addEvent(menu, 'click', function (e) {
if(nav.getAttribute('data-animate') == STATUS.hide) {
clearTimeout(timer); //防止连续不断的点击,出现bug
nav.style.display = 'block';
removeClass(nav, STATUS.hide);
addClass(nav, STATUS.show);
nav.setAttribute('data-animate', STATUS.show);
} else {
timer = setTimeout(function () {
nav.style.display = 'none';
}, 1000);
removeClass(nav, STATUS.show);
addClass(nav, STATUS.hide);
nav.setAttribute('data-animate', STATUS.hide);
}
}, false);
})();
效果示例:
睁不起了==睡觉了~呼噜~