解析JS运动

解析JS运动

物体运动原理:通过改变物体的位置,而发生移动变化。
方法:
      1.运动的物体使用绝对定位
      2.通过改变定位物体的属性(left、right、top、bottom)值来使物体移动。例如向右或左移动可以使用offsetLeft(offsetRight)来控制左右移动。
步骤:
    1、开始运动前,先清除已有定时器 (因为:是连续点击按钮,物体会运动越来越快,造成运动混乱)
    2、开启定时器,计算速度
    3、把运动和停止隔开(if/else),判断停止条件,执行运动

一.定时器

在javascritp中,有两个关于定时器的专用函数,它们是:
1.倒计定时器:timename=setTimeout("function();",delaytime);
2.循环定时器:timename=setInterval("function();",delaytime);
  function()是定时器触发时要执行的是事件的函数,可以是一个函数,也可以是几个函数,或者javascript的语句也可以,单要用;隔开;delaytime则是间隔的时间,以毫秒为单位。
  倒计时定时器就是在指定时间后触发事件,而循环定时器就是在间隔时间到来时反复触发事件,其区别在于:前者只是作用一次,而后者则不停地作用。
  倒计时定时器一般用于页面上只需要触发一次的的情况,比如点击某按钮后页面在一定时间后跳转到相应的站点,也可以用于判断一个浏览者是不是你的站点上的“老客”,如果不是,你就可以在5秒或者10秒后跳转到相应的站点,然后告诉他以后再来可以在某个地方按某一个按钮就可以快速进入。
  循环定时器一般用于站点上需要从复执行的效果,比如一个javascript的滚动条或者状态栏,也可以用于将页面的背景用飞雪的图片来表示。这些事件需要隔一段时间运行一次。
  有时候我们也想去掉一些加上的定时器,此时可以用clearTimeout(timename) 来关闭倒计时定时器,而用clearInterval(timename)来关闭循环定时器。

二.运动研究

1.运动:匀速运动(让物体动起来)

对定时器的使用
给DIV加绝对定位
offsetLeft

问题:到达某个特定位罝停符
解决:做判断,符合条件时关掉定时器(存定时器timer)
速度变慢(一般不动时间,而是改数字-速度)
用变量存速度

问题:取7时,offsetLeft没有等于300的时候,div停不下来
解决:>=300 //停在 301

问题:到300后点击按钮还继续走
原因:点击按钮,执行函数,开定时器(执行当前函数一至少执行一次)
解决:加else (没有到达目标之前才执行)

问题:连续点击,速度变快
原因:每点击一次就开一个定时器,点击几次就有几个定时器同时工作
解决:保证每次只有一个定时器工作,先cearlnterval ()

示例1,分享到:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>分享到</title>
<style>
#div1 {width:150px; height:200px; background:green; position:absolute; left:-150px;}
#div1 span {position:absolute; width:20px; height:60px; line-height:20px; background:blue; right:-20px; top:70px;}
</style>
<script>
window.onload=function ()
{
    var oDiv=document.getElementById(‘div1‘);

    oDiv.onmouseover=function ()
    {
        startMove(0);
    };
    oDiv.onmouseout=function ()
    {
        startMove(-150);
    };
};

var timer=null;

function startMove(iTarget)
{
    var oDiv=document.getElementById(‘div1‘);

    clearInterval(timer);
    timer=setInterval(function (){
        var speed=0;

        if(oDiv.offsetLeft>iTarget)
        {
            speed=-10;
        }
        else
        {
            speed=10;
        }

        if(oDiv.offsetLeft==iTarget)
        {
            clearInterval(timer);
        }
        else
        {
            oDiv.style.left=oDiv.offsetLeft+speed+‘px‘;
        }
    }, 30);
}
</script>
</head>

<body>
<div id="div1">
    <span>分享到</span>
</div>
</body>
</html>

效果如下:

示例2,淡入淡出:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>淡入淡出</title>
<style>
#div1 {width:200px; height:200px; background:red; filter:alpha(opacity:30); opacity:0.3;}
</style>
<script>
window.onload=function ()
{
    var oDiv=document.getElementById(‘div1‘);

    oDiv.onmouseover=function ()
    {
        startMove(100);
    };
    oDiv.onmouseout=function ()
    {
        startMove(30);
    };
};

var alpha=30;
var timer=null;

function startMove(iTarget)
{
    var oDiv=document.getElementById(‘div1‘);

    clearInterval(timer);
    timer=setInterval(function (){
        var speed=0;

        if(alpha<iTarget)
        {
            speed=10;
        }
        else
        {
            speed=-10;
        }

        if(alpha==iTarget)
        {
            clearInterval(timer);
        }
        else
        {
            alpha+=speed;

            oDiv.style.filter=‘alpha(opacity:‘+alpha+‘)‘;
            oDiv.style.opacity=alpha/100;
        }
    }, 30);
}
</script>
</head>

<body>
<div id="div1"></div>
</body>
</html>

效果如下:

匀速运动的停止条件

距离足够近

示例3,匀速运动的停止条件:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>匀速运动的停止条件</title>
<style>
#div1 {width:100px; height:100px; background:red; position:absolute; left:600px; top:50px;}
#div2 {width:1px; height:300px; position:absolute; left:300px; top:0; background:black;}
#div3 {width:1px; height:300px; position:absolute; left:100px; top:0; background:black;}
</style>
<script>
var timer=null;

function startMove(iTarget)
{
    var oDiv=document.getElementById(‘div1‘);

    clearInterval(timer);
    timer=setInterval(function (){
        var speed=0;

        if(oDiv.offsetLeft<iTarget)
        {
            speed=7;
        }
        else
        {
            speed=-7;
        }

        if(Math.abs(iTarget-oDiv.offsetLeft)<=7)
        {
            clearInterval(timer);

            oDiv.style.left=iTarget+‘px‘;
        }
        else
        {
            oDiv.style.left=oDiv.offsetLeft+speed+‘px‘;
        }
    }, 30);
}
</script>
</head>

<body>
<input type="button" value="到100" onclick="startMove(100)" />
<input type="button" value="到300" onclick="startMove(300)" />
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
</body>
</html>

2.变速运动(缓冲运动)

逐渐变慢,最后停止
距离越远速度越大
    速度有距离决定
    速度=(目标值-当前值)/缩放系数
    如果没有缩放系数t速度太大,瞬间到达终点.没有过程

问题:并没有真正到达300
原因:速度只剩0.9    //像素是屏幕能够显示的最/J库位,并不会四舍五入掉
Math.ceil ()向上取整
Math.floor ()向下取整

问题:向左走,又差一块--Math.floor ()
判断:三目 speed=speed>0 ? Math.ceil ( speed ): Math.floor ( speed )

示例,缓冲运动:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>缓冲运动</title>
<style>
#div1 {width:100px; height:100px; background:red; position:absolute; left:600px; top:50px;}
#div2 {width:1px; height:300px; position:absolute; left:300px; top:0; background:black;}
</style>
<script>
function startMove()
{
    var oDiv=document.getElementById(‘div1‘);
    setInterval(function (){
        var speed=(300-oDiv.offsetLeft)/10;
        speed=speed>0?Math.ceil(speed):Math.floor(speed);

        oDiv.style.left=oDiv.offsetLeft+speed+‘px‘;

        document.title=oDiv.offsetLeft+‘,‘+speed;
    }, 30);
}
</script>
</head>

<body>
<input type="button" value="开始运动" onclick="startMove()" />
<div id="div1"></div>
<div id="div2"></div>
</body>
</html>

效果如下:

3.多物体运动

多个div ,鼠标移入变宽
    运动框架传参obj,知道让哪个物体动起来
    用到缓冲一定要取整

问题:div没运动回去    //清除前一个定时器
原因:只有一个定时器
解决:加物体上的定时器,使每个物体都有一个定时器。定时器作为物体属性

多个div淡入淡出
首先关闭物体上的定时器
经验:多物体运动框架所有东西都不能共用

问题:不是因为定时器,而是因为alpha
解决:作为属性附加到物体上    /不以变量形式存在

offset 的 bug

加border变宽

offsetWith并不是真正的width ,它获取的是盒模型尺寸
解决:躲着  宽度扔到行间,parselnt ( oDiv.style.width )

进一步解决: getStyle ( obj, name ) currentStyle , getComputedStyle
加border ,只要offset就有问题 去掉offset

示例,多物体运动:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
div {width:100px; height:50px; background:red; margin:10px; border:10px solid black;}
</style>
<script>
window.onload=function ()
{
    var aDiv=document.getElementsByTagName(‘div‘);

    for(var i=0;i<aDiv.length;i++)
    {
        aDiv[i].timer=null;

        aDiv[i].onmouseover=function ()
        {
            startMove(this, 400);
        };

        aDiv[i].onmouseout=function ()
        {
            startMove(this, 100);
        };
    }
};

function startMove(obj, iTarget)
{
    clearInterval(obj.timer);
    obj.timer=setInterval(function (){
        var speed=(iTarget-obj.offsetWidth)/6;
        speed=speed>0?Math.ceil(speed):Math.floor(speed);

        if(obj.offsetWidth==iTarget)
        {
            clearInterval(obj.timer);
        }
        else
        {
            obj.style.width=obj.offsetWidth+speed+‘px‘;
        }
    }, 30);
}
</script>
</head>

<body>
<div></div>
<div></div>
<div></div>
</body>
</html>

效果如下:

4.任意值运动

任意值运动的单位分为透明度和px。

px单位的任意值

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
div {width:200px; height:200px; margin:20px; float:left; background:yellow; border:10px solid black; font-size:14px;}
</style>
<script>
window.onload=function ()
{
    var oDiv1=document.getElementById(‘div1‘);
    oDiv1.onmouseover=function (){startMove(this, ‘height‘, 400);};
    oDiv1.onmouseout=function (){startMove(this, ‘height‘, 200);};

    var oDiv2=document.getElementById(‘div2‘);

    oDiv2.onmouseover=function (){startMove(this, ‘width‘, 400);};
    oDiv2.onmouseout=function (){startMove(this, ‘width‘, 200);};

    var oDiv3=document.getElementById(‘div3‘);
    oDiv3.onmouseover=function (){startMove(this, ‘fontSize‘, 50);};
    oDiv3.onmouseout=function (){startMove(this, ‘fontSize‘, 14);};

    var oDiv4=document.getElementById(‘div4‘);
    oDiv4.onmouseover=function (){startMove(this, ‘borderWidth‘, 100);};
    oDiv4.onmouseout=function (){startMove(this, ‘borderWidth‘, 10);};
};

function getStyle(obj, name)
{
    if(obj.currentStyle){return obj.currentStyle[name];}
    else{return getComputedStyle(obj, false)[name];}
}

function startMove(obj, attr, iTarget)
{
    clearInterval(obj.timer);
    obj.timer=setInterval(function (){
        var cur=parseInt(getStyle(obj, attr));

        var speed=(iTarget-cur)/6;
        speed=speed>0?Math.ceil(speed):Math.floor(speed);

        if(cur==iTarget)
        {
            clearInterval(obj.timer);
        }
        else
        {
            obj.style[attr]=cur+speed+‘px‘;
        }
    }, 30);
}
</script>
</head>

<body>
<div id="div1">变高</div>
<div id="div2">变宽</div>
<div id="div3">safasfasd</div>
<div id="div4"></div>
</body>
</html>

效果如下:

透明度的任意值,需要做判断:

判断
var cur=0
if ( attr== ‘opacity ‘){
cur=parseFloat ( getStyle ( obj, attr)) *100
}else{

}
设置样式判断
if ( attr== ‘opacity ‘){
obj.style.fiIter = ‘alpha ( opacity: ‘( cur+speed ) + ‘)‘
obj.style.opacity= ( cur+speed ) /100
}else{

}

5.链式运动

多出来的一个参数,只有传进去的时候才调用
鼠标移入变宽,结束之后弹出abc
先横向展开.再以向展开
鼠标移出,先变回不透明,变矮,变窄

三.封装运动框架(源码下载:https://github.com/jingwhale/jsmove/blob/master/move.js)

基于以上的分析与总结,封装运动框架move.js如下:

function getStyle(obj, name)
{
    if(obj.currentStyle)
    {
        return obj.currentStyle[name];
    }
    else
    {
        return getComputedStyle(obj, false)[name];
    }
}

function startMove(obj, json, fnEnd)
{
    clearInterval(obj.timer);
    obj.timer=setInterval(function (){
        var bStop=true;        //假设:所有值都已经到了

        for(var attr in json)
        {
            var cur=0;

            if(attr==‘opacity‘)
            {
                cur=Math.round(parseFloat(getStyle(obj, attr))*100);
            }
            else
            {
                cur=parseInt(getStyle(obj, attr));
            }

            var speed=(json[attr]-cur)/6;
            speed=speed>0?Math.ceil(speed):Math.floor(speed);

            if(cur!=json[attr])
                bStop=false;

            if(attr==‘opacity‘)
            {
                obj.style.filter=‘alpha(opacity:‘+(cur+speed)+‘)‘;
                obj.style.opacity=(cur+speed)/100;
            }
            else
            {
                obj.style[attr]=cur+speed+‘px‘;
            }
        }

        if(bStop)
        {
            clearInterval(obj.timer);

            if(fnEnd)fnEnd();
        }
    }, 30);
}

move.js运动框架基本满足现在网页上所有动画的需求(不包括css3)。

四.应用

应用1,完成如下效果:

js代码如下:

<script src="move.js"></script>
<script>
window.onload=function ()
{
    var oDiv=document.getElementById(‘play‘);
    var aBtn=oDiv.getElementsByTagName(‘ol‘)[0].getElementsByTagName(‘li‘);
    var oUl=oDiv.getElementsByTagName(‘ul‘)[0];

    var now=0;
    for(var i=0;i<aBtn.length;i++)
    {
        aBtn[i].index=i;
        aBtn[i].onclick=function ()
        {
            now=this.index;
            tab();
        };
    }

    function tab()
    {
        for(var i=0;i<aBtn.length;i++)
        {
            aBtn[i].className=‘‘;
        }
        aBtn[now].className=‘active‘;
        startMove(oUl, {top: -150*now});
    }

    function next()
    {
        now++;
        if(now==aBtn.length){now=0;}
        tab();
    }

    var timer=setInterval(next, 2000);

    oDiv.onmouseover=function (){clearInterval(timer);};

    oDiv.onmouseout=function (){timer=setInterval(next, 2000);};
};
</script>
应用2,完成如下效果:

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
.....
</style>
<script type="text/javascript" src="move.js"></script>
<script type="text/javascript">
window.onload=function ()
{
    var oBtn=document.getElementById(‘but‘);
    var oBottom=document.getElementById(‘zns_bottom‘);
    var oBox=document.getElementById(‘zns_box‘);
    var oBtnClose=document.getElementById(‘btn_close‘);

    oBox.style.display=‘block‘;
    var initBottomRight=parseInt(getStyle(oBottom, ‘right‘));
    var initBoxBottom=parseInt(getStyle(oBox, ‘bottom‘));
    oBox.style.display=‘none‘;

    oBtn.onclick=openHandler;
    oBtnClose.onclick=closeHandler;

    function openHandler()
    {
        startMove(oBottom, {right: 0}, function (){
            oBox.style.display=‘block‘;
            startMove(oBox, {bottom: 0});
        });
        oBtn.className=‘but_hide‘;
        oBtn.onclick=closeHandler;
    }

    function closeHandler()
    {
        startMove(oBox, {bottom: initBoxBottom}, function (){
            oBox.style.display=‘none‘;
            startMove(oBottom, {right: initBottomRight}, function (){
                oBtn.className=‘but_show‘;
            });
        });
        oBtn.onclick=openHandler;
    }
};
</script>
</head>
<body>
    ......
</body>
</html>

源码下载:https://github.com/jingwhale/jsmove

-------------------------------------------------------------------------------------------------------------------------------------

转载需注明转载字样,标注原作者和原博文地址。

时间: 2024-08-19 03:22:50

解析JS运动的相关文章

浅解析js中的对象

浅解析js中的对象 说到对象,我首先想到的是每逢过年过节,长辈们老是开玩笑的问我“你找了对象没?”.不说大家都知道,这里的“对象”指的是“女朋友”,但是今天我想要说的js中的“对象”和我们生活中谈到的“对象”不是同一回事,但是其中也有着很多相似之处.    在讲js中的对象之前,我想先抛出几个疑问:    什么是对象?    对象有哪些?    对象能做什么?    如何创建对象?    如何对对象进行操作?    对象有特性么?有的话有哪些特性?    对象有属性么?有的话有哪些?对属性如何操

带无缝滚动的轮播图(含JS运动框架)

今天学习了一下轮播图的写作,想到前一阵学过的无缝滚动得思想,所以就把轮播与滚动结合了一下.不过我的代码的神逻辑我自己都不敢恭维,在没网没参照的情况下,只能硬着头皮往下写,希望跟大家共勉吧. js运动框架的代码如下: 1 //获取样式 2 function getStyle(obj,attr){ 3 if(obj.currentStyle){ 4 return obj.currentStyle[attr]; 5 }else{ 6 return getComputedStyle(obj,false)

JS运动从入门到兴奋1

hello,我是沐晴,一个充满了才华,却靠了照骗走江湖的前端妹子.在这个充满PS的年代,这你们都信,哈哈,废话不多说,今天要分享的是关注JS运动的知识.楼主一直认为,不管学习什么,核心思想才是王道,掌握了思想,不管需求怎么改变,我们都能把它玩弄于股掌之中...下面我们就由浅入深走进运动的世界吧. 首先来看最基础的运动:单个物体向右匀速运动到某一点停止      例子:一个按钮,一个div,点击按钮,让div向右运动到某一个位置暂停 // 原理: 1 获取物体当前的位置 oDiv.offsetle

关于js运动的一些总结

js运动实现,有两种.一种是速度版,另一种是时间版. 速度版是通过对速度的加减乘除,得出元素的运动数据.时间版是通过对时间进行Tween公式运算,得出元素的运动数据. 速度版运动优点:容易在运动过程中,对运动做一些修改. 时间版运动优点:切换或缩小浏览器页面,浏览器会对网页定时器进行停缓处理.这样会导致一些速度版运动bug.因为时间版运动是通过记录时间变化区间,来对运动进行控制.所以不会有这种bug. 运动形式有:缓冲运动,碰撞运动,重力运动.缓冲运动,是速度自身也在变化的结果.碰撞运动,是碰撞

JS运动1 (转)

JS运动从入门到兴奋1 http://www.cnblogs.com/moqing/p/5666476.html hello,我是沐晴,一个充满了才华,却靠了照骗走江湖的前端妹子.在这个充满PS的年代,这你们都信,哈哈,废话不多说,今天要分享的是关注JS运动 的知识.楼主一直认为,不管学习什么,核心思想才是王道,掌握了思想,不管需求怎么改变,我们都能把它玩弄于股掌之中...下面我们就进入运动的世界吧. 首先来看最基础的运动:单个物体向右匀速运动到某一点停止      例子:一个按钮,一个div,

selenium+phantomjs解析JS

背景知识: PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG.PhantomJS可以用于页面自动化,网络监测,网页截屏,以及无界面测试等. Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7.8.9).Mozilla Firefo

简单的JS运动封装实例---侧栏分享到

1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5 <title>无标题文档</title> 6 <style> 7 #div1 {width: 100px; height: 200px; background: red;

js运动-完美运动框架

在上一篇的<js运动-同时运动>中说过,我们的运动框架还存在一个问题,那究竟是什么问题那?把上一篇的程序做一下调整 oDiv.onmouseover = function () { //startMove(oDiv,{width:300,height:300,opacity:30}); startMove(oDiv,{width:204,height:300,opacity:30}); } 在鼠标移入的时候,我们让width不变成300,而是变成204,看看会有什么变化那?? 从图可以看出,当

js运动动画

今天简单的学了一下js运动动画,再此感谢慕课网的这位老师http://www.imooc.com/view/167,讲的很不错. 下面是我整理出来的结果. 知识点一:速度动画. 1.首先第一步实现速度运动动画,封装一个函数,用到的知识是setInterval(function(){ oDiv.style.left=oDiv.offsetLeft+10+"px"; },30). 对于这里为什么要用到offsetLeft,我特意百度了一下,http://www.cnblogs.com/wo