zoukankan      html  css  js  c++  java
  • javascript中的动画的实现以及运动框架的编写(1)

    大家知道js可以做出好多很漂亮的动画,看上去很神奇,其实原理很简单,今天就讨论一下js动画的实现以及如何编写可以反复重用的运动框架。

    首先做一个简单的例子,我这里有一个长50px 宽20px的长条形div 现在我想让鼠标停在上面的时候这个长条变为长1000px宽20px的超级长条,然后当鼠标移开的时候再变回50px长。

    下面看一下我写的代码:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>无标题文档</title>
    <style type="text/css">
    .div1{
        width:50px;
        height:20px;
        background:red;
        margin:4px;
    }
    </style>
    <script type="text/javascript">
    var odiv1 = document.getElementsByTagName("div");
    window.onload = function(){
        odiv1[0].onmouseover = function(){
            odiv1[0].style.width = 1000+"px";
        }
        odiv1[0].onmouseout = function(){
            odiv1[0].style.width = 50+"px";
        }
    }
    </script>
    </head>
    
    <body>
    <div class="div1"></div>
    </body>
    </html>

    这里可以看到一个非常死板的动画效果,50px长的div瞬间变成了1000px长,然后又瞬间变回来。

    严格的说,这算是个p动画效果,动画的本质是人眼睛可以保存前1微秒看到的影响,从而将死板的动作看成是平滑的动作,我们现在就要改善这个死板的动作。

    其实我们可以将如此死板的动作理解为速度太快了,一瞬间就从50变到1000了,如果我们能让他先从50变成100,然后再变成150,最后变成1000,动作必然变得更加平滑,现在我让他同样时间内只变化少量px最终变成1000的时候,就停止。我可以用一个定时器来实现这一点。

    看我改善后的javascript部分的代码如下:

    var odiv1 = document.getElementsByTagName("div");
    window.onload = function(){
        var speed = 5;
        var timer = null;
        odiv1[0].onmouseover = function(){
            clearInterval(timer);
            timer = setInterval(function(){
                if(odiv1[0].offsetWidth == 1000){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = odiv1[0].offsetWidth+speed+"px";
                }
            },30)
        }
        odiv1[0].onmouseout = function(){
            clearInterval(timer);
            timer = setInterval(function(){
                if(odiv1[0].offsetWidth == 50){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = (odiv1[0].offsetWidth-speed)+"px";
                }
            },30)
        }
    }

    现在我们看到了一个非常平滑的动画,并且speed可以移动,虽然这样的动画效果已经让你感觉很满意了,但是,他依然不够美观,这是一个匀速运动,我们喜欢看到的是一种缓冲运动,现在我们在speed上下文章,把speed定义为距离目标越近则越小,可以实现缓冲运动。代码改善如下:

    var odiv1 = document.getElementsByTagName("div");
    window.onload = function(){
        var timer = null;
        odiv1[0].onmouseover = function(){
            clearInterval(timer);
            timer = setInterval(function(){
                var speed = (1000-odiv1[0].offsetWidth)/8;
                if(odiv1[0].offsetWidth == 1000){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = odiv1[0].offsetWidth+speed+"px";
                }
            },30)
        }
        odiv1[0].onmouseout = function(){
            clearInterval(timer);
            timer = setInterval(function(){
                var speed = (odiv1[0].offsetWidth-50)/8;
                if(odiv1[0].offsetWidth == 50){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = (odiv1[0].offsetWidth-speed)+"px";
                }
            },30)
        }
    }

    这时候看到的就是变速运动了,这里面还存在两个小问题,首先是,代码几乎没有重用性,我们在两个事件中的代码几乎相同,所以可以封装为同一段代码。其次,speed存在小数行为,小数是我们无法容忍的,不解释……下面继续对代码进行改进。

    首先,我们需要对相同代码进行封装,我们现在把目标改为不确定,也就是说我们把div想要变成多大作为参数传进函数中,既能增加div长度也能减少,同时当鼠标移开的时候div恢复原来长度。下面看封装的代码:

    window.onload = function(){
        var timer = null;
        function startMove(target){
            clearInterval(timer);
            timer = setInterval(function(){
                var speed = (target-odiv1[0].offsetWidth)/8;
                if(odiv1[0].offsetWidth == target){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = odiv1[0].offsetWidth+speed+"px";
                }
            },30)
        }
        var odiv1 = document.getElementsByTagName("div");
        odiv1[0].onmouseover = function(){
            startMove(20);
        }
        odiv1[0].onmouseout = function(){
            startMove(50);
        }
    }

    这段代码封装了startMove()函数,看到效果完全跟原来相同。

    下面我们来解决小数的问题:

    我们可以利用javascript的Math对象的方法将小数转换为整数,具体如何转换不再赘述,下面是我改善的代码:

    window.onload = function(){
        var timer = null;
        function startMove(target){
            clearInterval(timer);
            timer = setInterval(function(){
                var speed = (target-odiv1[0].offsetWidth)/8;
                if(speed>0){
                    speed=Math.ceil(speed);
                }
                else{
                    speed=Math.floor(speed);
                }
                if(odiv1[0].offsetWidth == target){
                    clearInterval(timer);
                }
                else{
                    odiv1[0].style.width = odiv1[0].offsetWidth+speed+"px";
                }
            },30)
        }
        var odiv1 = document.getElementsByTagName("div");
        odiv1[0].onmouseover = function(){
            startMove(20);
        }
        odiv1[0].onmouseout = function(){
            startMove(50);
        }
    }

    现在运动框架基本成型,最后我们需要的不仅仅是对一个对象进行运动,我们有时候一个页面需要很多元素需要动画,这时候我们需要对函数进行进一步封装,把运动的对象也放进函数中进行封装。

    下面是代码:

        function startMove(obj,target){
            clearInterval(obj.timer);
            obj.timer = setInterval(function(){
                var speed = (target-obj.offsetWidth)/8;
                if(speed>0){
                    speed=Math.ceil(speed);
                }
                else{
                    speed=Math.floor(speed);
                }
                if(obj.offsetWidth == target){
                    clearInterval(obj.timer);
                }
                else{
                    obj.style.width = obj.offsetWidth+speed+"px";
                }
            },30)
        }
        window.onload = function(){
            var odiv1 = document.getElementsByTagName("div");
            for(var i=0;i<odiv1.length;i++){
                odiv1[i].timer = null;
                odiv1[i].onmouseover = function(){
                    startMove(this,200);
                }
                odiv1[i].onmouseout = function(){
                    startMove(this,50);
                }
            }
        }

    就这样我们建立了一个简单的运动框架实现了动画效果。并且代码具有一定的重用性。

  • 相关阅读:
    设计模式学习总结系列应用实例
    【研究课题】高校特殊学生的发现及培养机制研究
    Linux下Oracle11G RAC报错:在安装oracle软件时报file not found一例
    python pro practice
    openstack python sdk list tenants get token get servers
    openstack api
    python
    git for windows
    openstack api users list get token get servers
    linux 流量监控
  • 原文地址:https://www.cnblogs.com/bianbiangege/p/3423683.html
Copyright © 2011-2022 走看看