【原生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;
    }
}

版权声明:本文为博主原创文章,转载还请留言。

时间: 2024-12-13 07:35:49

【原生JS组件】javascript 运动框架的相关文章

原生js设计的运动框架

这个运动框架适合绝大多数的动画运动,话不多说,先上代码: function move(obj,json,fn){ //关闭定时器 clearInterval(obj.timer); //开启定时器 obj.timer = setInterval(function(){ var bStop = true; for(var attr in json){ //先判断是否是透明度 var iCur; if(attr == "opacity"){ //parseInt:防止在IE出现闪烁问题 i

【repost】JavaScript运动框架之速度时间版本

一.JavaScript运动框架之速度版 1.1 运动框架的实现思路 运动,其实就是在一段时间内改变 left . right . width . height . opactiy 的值,到达目的地之后停止 位移 top,left 折叠 width,height 淡入淡出 opacity 时间有关系 setInterval setTimeout 用javascript直接获取行间样式很容易,但如果要获取非行间样式那我们只能借助函数了.我这里编写了一个名为getStyle的函数,专门处理取非行间的

js实现的运动框架代码实例

js实现的运动框架代码实例:元素的运动效果在大量的场景中都有应用,最典型的一个就是网站的客服系统,一般都会随着滚动条运动,本章节就介绍一下js的一个运动框架实例,希望能够给需要的朋友带来借鉴作用.代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www.softwh

转 JavaScript 运动框架 Step by step

1,运动原理 Js运动,本质来说,就是让 web 上 DOM 元素动起来.而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等.动画的原理就是把不同状态的物体,串成连续的样子,就像一本书,画了几个小人,然后 一翻书,就看见小人在动.js动画也一样.不同状态的DOM,用定时器控制,就能得到动画效果. [javascript] view plain copy window.onload = function(){ var oBtn = document.getElemen

JavaScript 运动框架(介绍及原理)

1,运动原理 Js运动,本质来说,就是让 web 上 DOM 元素动起来.而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等.动画的原理就是把不同状态的物体,串成连续的样子,就像一本书,画了几个小人,然后一翻书,就看见小人在动.js动画也一样.不同状态的DOM,用定时器控制,就能得到动画效果. 1 window.onload = function(){ 2 var oBtn = document.getElementById('btn'); 3 oBtn.oncli

JS的完美运动框架

function getStyle(obj, name) { if(obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, false)[name]; } } //注意:在多物体运动框架中,所有东西都不能公用 !否则出问题,BUG:将必要的变量加到物体的属性中就行.即:属性与运动对象绑定:速度.其他属性值(如透明度等等) function startMove(obj, jso

JS 之完美运动框架

完美运动框架是对原来的任意值运动框架的改善和效率的提升,即利用了json对属性进行封装,从而提高效率: window.onload=function(){ var oDiv=document.getElementsByTagName('div')[0]; oDiv.onmouseover=function(){ move(this,{width:200,height:200}); } } function getStyle(obj,attr){ if (obj.currentStyle) { r

js之任意值运动框架

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

javascript运动框架

//运动框架//使用json传参的方式function sportFrame(obj,json,fun){    var timer;    clearInterval(obj.timer);    obj.timer=setInterval(function(){        var Stop=true;        for(var name in json){            var val=0;            //判断是不是透明度            if(name==