javascript原生代码实现通用运动框架

首先对常见的运动做一个总结

一、运动总结
1、匀速运动
                1.速度不变,临界判断尤为重要,判断不好可能超出目标点。可以用绝对值 Math.abs(now-target)<speed ,最后1次手动运动到目标点
2、缓冲运动
               1.速度逐渐变小,是变减速运动,
               2.临界问题就不用管了,速度最后会变为1个像素的移动(直接取整)
               3.速度是逐渐减小为0,但是都是>0的,所以是单方向的运动
3、弹性运动
               1.速度与缓冲运动一样逐渐变小,但是速度可以<0 ,所以是双方向的运动
               2.是按一定比例摩擦力减小速度,并不是到目标点速度为0,所以在目标点的时候还有速度
               3.使用范围比较窄,如果变换的属性 会越界,就不适合使用。


二、通用运动框架

1、我们在写一个物体运动的时候,基本上会有这么几个过程,以下归纳


1.清除当前物体定时器定时器
2.设置定时器
3.得到当前位置
4.计算速度
5.停止检查
6.
运动


2.以下是框架代码

/**
 * 通用运动框架,支持多个对象同时运动
 * @param obj 运动对象
 * @param json 需要变化的属性键值对 值为目的地的值
 * @param func 运动完成后执行函数
 */
function startMove(obj,json,func){
    //清除定时器
    clearInterval(obj.timer);
    //设置定时器
    obj.timer = setInterval(function(){
        //得到当前位置
        var isStop = true;
        for(var atrr in json){
            var iNowPosition = null;
            if(atrr == 'opacity'){
                iNowPosition =  parseInt(parseFloat(getStyle(obj,atrr))*100);         //避免浮点数
            }else{
                iNowPosition  = parseInt(getStyle(obj,atrr));
            }
            //计算速度
            var iSpeed = (json[atrr]-iNowPosition)/8;
            iSpeed = iSpeed>0 ?Math.ceil(iSpeed):Math.floor(iSpeed);

            //停止检查
            if(iNowPosition != json[atrr]){                                            //当所有的都到达才停止
                isStop = false;
            }else{
                isStop  = true;
            }

            if(atrr == 'opacity'){
                obj.style.filter = 'alpha:opacity('+(iNowPosition+iSpeed)+')';
                obj.style.opacity = (iNowPosition+iSpeed)/100;
            }else{
                obj.style[atrr] = iNowPosition + iSpeed + 'px'; //移动物体
            }
        }

        if(isStop){
            clearInterval(obj.timer);
            if(func){
                func();
            }
        }

    },30)
}
3.以下是一个简单的例子,效果大家可以自己试试

<style type="text/css">
        div {
            width: 100px;
            height: 100px;
            background: red;
            margin-top: 50px;
            border: 1px solid red;
        }
    </style>

    <script type="text/javascript">
        window.onload = function () {
            var oDivs = document.getElementsByTagName ('div');

            oDivs[0].onmouseover = function () {
                startMove (this, {width: 500});
            }
            oDivs[0].onmouseout = function () {
                startMove (this, {width: 100});
            }

            oDivs[1].onmouseover = function () {
                startMove (this, {height: 150});
            }
            oDivs[1].onmouseout = function () {
                startMove (this, {height: 100});
            }

            oDivs[2].onmouseover = function () {
                startMove (this, {'opacity': 100});
            }
            oDivs[2].onmouseout = function () {
                startMove (this, {'opacity': 30});
            }

        }

    </script>
</head>
<body>

<div></div>
<div></div>
<div></div>

4.注意事项

在写运动框架的时候,遇到了一些问题,和关键点,在此总结

1.开始运动前先删掉原来的定时器
2.运动和停止的处理分开并且不能同时执行
3.速度取整,最小单位不能小于1像素
4.不要用offsetWidth  它会包含除了内容以外 border padding 计算的时候会出现额外值,出现意外情况

5.多物体运动,所有的东西都不能公用,全部设置为该物体的属性

6.用数字进行计算的时候,注意用Number转一下。避免出错

7.js字符串转数字  str*1

8.运动处理中,如果有除法,则很容易出现小数,那么就要取整

9.尽量避免使用小数,用小数就会出问题,通过单位转换和省掉小数部分来避免


三、弹性运动框架

	
var iSpeed = 0;
        var left = 0;
        function flexMove(ele,iTarget){
                clearInterval(ele.timer);
                ele.timer = setInterval(function(){
                    iSpeed += (iTarget-ele.offsetLeft)/5;
                    iSpeed *= 0.7;      //弹性运动,相当于有一个摩擦力,速度越来越小,方向不停的变化(由speed的正负来确定)

                    left += iSpeed       //这个地方没有用offSetLeft 来算移动距离,因为不支持小数会自己省掉,造成误差
                    if(Math.abs(iSpeed) < 1 && Math.abs(iTarget - left) < 1){
                        clearInterval(ele.timer);
                        iSpeed = 0;
                        ele.style.left = iTarget + "px"; //当速度小于1个像素,或者距离目的地小于1个像素,则直接到达目标点
                    }else{
                        ele.style.left = left  + "px";  //速度根据计算出来的speed不停叠加
                    }

                },30)
        }

1.下面是一个实例,实现了菜单下,1个小条的弹性运动

 <style type="text/css">
        li{ list-style: none;} img{ border: none;} ul{ padding: 0; margin: 0;}
        #ul1 { width: 408px; margin: 0 auto; position: relative;}
        #ul1 li{ width: 100px; height: 30px;line-height: 20px; border: 1px solid; float: left; text-align: center; }
        #ul1 .bg{ background-color: red; height: 5px; border: 1px solid black; position: absolute;top:25px; left: 0; }
    </style>
    <script type="text/javascript">
        window.onload = function(){
            var bg = document.getElementsByClassName('bg')[0];
            var ali = document.getElementById('ul1').getElementsByTagName('li');
            for (var i = 0; i < ali.length-1; i++) {
                var obj = ali[i];
                obj.onmouseover = function(){
                    flexMove(bg,this.offsetLeft);
                }
            }
        }


    </script>
</head>
<body>
    <ul id="ul1">
        <li>相见相见</li>
        <li>相见相见</li>
        <li>相见相见</li>
        <li>相见相见</li>
        <li class="bg"></li>
    </ul>
</body>



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值