一、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);
})();

效果示例:
css3-animation

睁不起了==睡觉了~呼噜~

标签: none

添加新评论