zoukankan      html  css  js  c++  java
  • 【原生JS组件】javascript 运动框架

    大家都知道JQuerry有animate方法来给DOM元素进行运动,CSS3中也有transition、transform来进行运动。而使用原生的Javascript来控制元素运动,须要写非常多运动的细节以及兼容。

    然而。当你的BOSS不让你使用庞大的JQ框架,并且你开发的产品也须要在一些不兼容CSS3的浏览器运行的时候。你是否认为每次都要开个定时器来琢磨运动该怎么进行,是件非常费力的事情呢?

    那么福利来了,笔者近期总结了两个经常使用的运动框架,并将其写成组件,
    仅仅要依照以下的方法调用。就可以方便使用。

    1.在你的页面中引入js

    <script src="Mover.js"></script>

    2.在你的js代码中创建Mover对象

    <script>
    window.onload=function(){
        var mover = new Mover();
    };
    </script>

    3.開始使用mover!
    使用方法说明:笔者写的组件包含了两种运动框架供使用。一种是基于速度的;一种是基于时间的。让我们来先看看基于速度的运动框架的使用方法

    startMoveBySpeed(obj, json, endFn);

    參数obj : 传入要运动的对象

    參数json : 以json的形式传入要运动的属性,包含left、top、width、height等以px为单位的属性和透明度opacity,他们的值是运动的终点

    參数endFn(可选) : 结束运动后要运行的方法

    <script>
    //基于速度的运动框架使用方法
    window.onload=function(){
        //得到你要运动的元素
        var oDiv = document.getElementsByTagName('div')[0];
    
        //使用运动框架
        var mover = new Mover();
        oDiv.onclick=function(){    
            mover.startMoveBySpeed(this,{'left':200,'width':300,'opacity':50});
        //使oDiv的left运动到200px,宽度变为300px,透明度变为50%
        }
    
    };
    </script>

    让我们来看看第二种基于时间的运动框架

    startMoveByTime(obj, json, options, endFn )

    參数obj : 传入要运动的对象

    參数json : 以json的形式传入要运动的属性。包含left、top、width、height等以px为单位的属性和透明度opacity。他们的值是运动的终点

    參数options : 以json的形式传入传入运动的总时间和运动方式,如:
    {
    ‘times’ : 1000。//运动总时间为1s
    ‘fx’ : ‘linear’ // 运动形式为匀速
    }
    当options传入參数为空json{}时,就使用默认设置(运动时间500ms,运动形式为匀速)

    參数endFn(可选) : 结束运动后要运行的方法

    //基于事件的运动框架使用方法
    window.onload=function(){
        //得到你要运动的元素
        var oDiv = document.getElementsByTagName('div')[0];
        //使用运动框架
        var mover = new Mover();
        oDiv.onclick=function(){
            mover.startMoveByTime(
                this, 
                {'left':500,'top':200}, 
                {'times':1000,'fx':'easeIn'}, 
                function(){
                    mover.startMoveByTime(this,{'opacity':20},{});
            });
            //使oDiv的left变为500px,高度变为200px,结束上述运动后再使透明度变为20%
        }
    }

    如今来说说两种方式的差别吧。使用第一种方式进行运动时。元素的各项须要改变的属性的运动速度同样,而因为每项属性起点到终点的距离不一样。所以各项属性到达运动终点的时间也不一样。

    而第二种运动直接固定了运动总时间同样,所以全部传入參数的属性一起改变、一起终止。

    以下是Mover.js组件的代码,笔者乃菜鸟一仅仅,欢迎指正。后面有时间也会将弹性运动、碰撞运动、重力运动一起写入框架

    /*
        js原生运动组件
    */
    
    //Mover构造函数
    function Mover(){
        this.setting = {
            'times' : 500,
            'fx' : 'linear'
        }
    }
    
    //获取当前样式
    Mover.prototype.getStyle = function(obj,attr)
    {
        return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
    }
    
    //获取当前时间
    Mover.prototype.now = function(){
            return (new Date()).getTime();
    }
    
    //速度版运动框架
    Mover.prototype.startMoveBySpeed = function (obj,json,fnEnd)
    {
        clearInterval(obj.timer);
        _this = this;
        obj.timer = setInterval(function(){
            obj.bStop = true;
            for(var attr in json)
            {
                var cur = 0;
                var speed = 0;
                if(attr === 'opacity')
                {
                    cur = _this.getStyle(obj,attr);
                    cur = Math.round( parseFloat(cur*100) );
                }
                else
                {
                    cur = parseInt(_this.getStyle(obj,attr));
                }
    
                var speed = (json[attr]-cur)/8;
    
                speed = speed ? Math.ceil(speed):Math.floor(speed);
    
                if(cur !== json[attr])
                {
                    obj.bStop = false;
                }
    
                if(attr === 'opacity')
                {
                    obj.style.opacity = (cur+speed)/100;
                    obj.style.filter = 'Alpha(opacity:'+(cur+speed)+')';
                }
                else
                {
                    obj.style[attr] = (cur+speed)+'px';
                }
            }
    
            if(obj.bStop)
            {
                clearInterval(obj.timer);
                fnEnd && fnEnd.call(obj);
            }
    
        },20);
    }
    
    //时间版运动框架
    Mover.prototype.startMoveByTime = function(obj,json,options,endFn){
        //对于时间版框架来说。初始值b是固定的,所以写在定时器外面
        var _this = this;
        //默认设置
        extend(_this.setting,options);
    
        var iCur = {};
        //获取当前值
        for(attr in json)
        {
            iCur[attr] = 0;
    
            if(attr === 'opacity')
            {
                iCur[attr] = Math.round( parseFloat( _this.getStyle(obj,attr) )*100 );
            }else{
                iCur[attr] = parseInt( _this.getStyle(obj,attr) );
            }
    
        };
    
        var iStartTime = _this.now();
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
            var iCurTime = _this.now();
            var t = _this.setting.times-
            Math.max(0,iStartTime-iCurTime+_this.setting.times);
            for(attr in json)
            {   
                /*
                    Tween[fx]函数4个參数
                    t:current  time(当前时间)
                    b:beginning  value(初始值)
                    c: change  in  value(变化量)
                    d:duration(持续时间)
                    return  (目标点)   
                */
                var value = _this.Tween[_this.setting.fx](
                    t,                      //t  0~times
                    iCur[attr],             //b
                    json[attr]-iCur[attr],  //c
                    _this.setting.times                     //d
                 );
                if(attr === 'opacity')
                {
                    obj.style[attr] =  parseFloat(value/100);
                    obj.style.filter = 'alpha(opacity:'+value+')';
                }else{
                    obj.style[attr] = value + 'px';
                }
    
            }
    
            if( t === _this.setting.times )
            {
                clearInterval(obj.timer);
                endFn && endFn.call(obj);
            }
        },13);
    
    }
    //覆盖默认设置
    function extend(child,father){
        for(var attr in father)
        {
            child[attr] = father[attr];
        }
    }
    //Tween运动算法
    Mover.prototype.Tween = {
        /*
            4个參数
            t:current  time(当前时间)
            b:beginning  value(初始值)
            c: change  in  value(变化量)
            d:duration(持续时间)
            return  (目标点)
    
        */
    
        linear: function (t, b, c, d){  //匀速
            return c*t/d + b;
        },
        easeIn: function(t, b, c, d){  //加速曲线
            return c*(t/=d)*t + b;
        },
        easeOut: function(t, b, c, d){  //减速曲线
            return -c *(t/=d)*(t-2) + b;
        },
        easeBoth: function(t, b, c, d){  //加速减速曲线
            if ((t/=d/2) < 1) {
                return c/2*t*t + b;
            }
            return -c/2 * ((--t)*(t-2) - 1) + b;
        },
        easeInStrong: function(t, b, c, d){  //加加速曲线
            return c*(t/=d)*t*t*t + b;
        },
        easeOutStrong: function(t, b, c, d){  //减减速曲线
            return -c * ((t=t/d-1)*t*t*t - 1) + b;
        },
        easeBothStrong: function(t, b, c, d){  //加加速减减速曲线
            if ((t/=d/2) < 1) {
                return c/2*t*t*t*t + b;
            }
            return -c/2 * ((t-=2)*t*t*t - 2) + b;
        }
    }
  • 相关阅读:
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现业务
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 开发流程
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 报表系统集成说明
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 处理报表
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据访问
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 分布式应用
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现插件
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 对象设计器使用帮助
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据层开发
    Jquery 中的CheckBox、 RadioButton、 DropDownList、CheckBoxList、RadioButtonList的取值赋值
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7025924.html
Copyright © 2011-2022 走看看