原生js写的动画函数在数值计算上遇到的问题-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

原生js写的动画函数在数值计算上遇到的问题

2016-03-11 13:39:54 2018 1

大神看下代码:我是学习慕课网上js动画效果时自己尝试制作的。
然后发现几个问题:
非匀速动画
无法控制动画持续时间
动画会在未达到终止条件时产生其他动作(尤其是在动态改变透明度的时候....js在计算小数点的时候那狗一样的长度,小数位居然能够达到8,9位之多,我也是醉了)

若是能修改麻烦替我修改下·····蟹蟹
若是有大神能写个简洁的原生js可多属性联动的动画函数提供参考那就更好了(必须要能够控制动画运行时间,且必须严格按照给定的终止条件终止的那种....)

<!doctype html>
    <html lang="en">
     <head>
   <meta http-equiv='content-type' content='text/html;charset=utf-8' />
      <script>
    /*--获取id--*/
    function $id(id){
      return document.getElementById(id);
    }
    /*----获取元素样式属性值--*/
    function $gs(ele,attr){
       if (ele.currentStyle)
         {
           return ele.currentStyle[attr];
         }else if (ele.style[attr]!==''){
              return ele.style[attr];
         }else{
          if (window.getComputedStyle(ele,null)[attr]!=='auto')
           {
             return window.getComputedStyle(ele,null)[attr];
           }else{
             return 0;
           }
         }
    } 
    
        // 多属性动画
        function animate(ele,time,json,fn){
           window.clearInterval(ele.timer);
           var fps=60/1000;
           ele.timer=window.setInterval(function(){
              for (var a in json)
               {
                 var curVal=(a.search('opacity')!==-1) ? parseFloat($gs(ele,a)) :parseInt($gs(ele,a)); // $gs 是自定义的获取元素某样式值德函数
                 var unit=(a.search('opacity')!==-1) ? '' : 'px';
                 var speed=(json[a]-curVal)/(fps*time);
                 if (speed>=0){
                   
                   if (curVal>=json[a]){
                     window.clearInterval(ele.timer);
                     ele.style[a]=json[a]+unit;
                     if (fn){
                       fn();
                     }
                   }else{
                     ele.style[a]=curVal+speed+unit;
                   }
                 }else{
                   if (curVal<=json[a]+0.05){
                     window.clearInterval(ele.timer);
                     ele.style[a]=json[a]+unit;
                     if (fn){
                       fn();
                     }
                   }else{
                     ele.style[a]=curVal+speed+unit;
                   }
                 }
               }
           },1/fps);
        }
    
     </script>
     </head>
     <body>
       <style>
         #animate{width:200px;height:200px;background-color:blue;}
       </style>
       <div id='animate'></div>
       
       <button id='pos'>开始多属性联动动画</button>
       <script>
         $id('pos').onclick=function(){  // $id(id) 是自定义的快捷获取元素的函数
           animate($id('animate'),1000,{width:500,opacity:0},function(){
             animate($id('animate'),1000,{width:200,opacity:1});
           });
         }
       </script>
     </body>
    </html>
取消 提交回答
全部回答(1)
  • a123456678
    2019-07-17 18:59:04

    你默认了fps为60帧,speed是每一帧的变化量
    但是实际上由于各种因素,浏览器的帧数是不确定的,每帧的时间间隔也是不确定的

    所以实际动画进程应该由起始时间与当前时间的差来计算
    animate执行的时候,通过Date.now()取起始时间,setInterval里,每次都去Date.now()取一次当前时间
    计算两个时间差elapsed与动画时间变量time的比例,就是style的变化比例
    当elapsed >= time时视为动画结束

    晚点有空的话上代码

    补代码

    多属性动画

    var interval = 1000 / 60;
    var animate = function animate(ele, time, json, fn) {
        if (ele.timer) return;
        var startTime = Date.now(),
            vals = [];
        for (var key in json) {
            var curVal = key.search('opacity') !== -1 ? parseFloat($gs(ele, key)) : parseInt($gs(ele, key)),
                unit = key.search('opacity') !== -1 ? '' : 'px';
    
            vals.push({ style: key, startVal: curVal, endVal: json[key], unit: unit });
        }
    
        ele.timer = setInterval(function () {
            var elapsed = Date.now() - startTime;
            if (elapsed >= time) {
                clearInterval(ele.timer);
                ele.timer = null;
                for (var i = 0; i < vals.length; i++) {
                    ele.style[vals[i].style] = vals[i].endVal + vals[i].unit;
                }
                
                fn && fn();
            } else {
                for (var i = 0; i < vals.length; i++) {
                    ele.style[vals[i].style] = vals[i].startVal + (vals[i].endVal - vals[i].startVal) * (elapsed / time) + vals[i].unit;
                }
            }
        }, interval);
    };
    0 0
相关问答

1

回答

怎么用原生的JavaScript模拟实现一起拖动桌面几个文件?求思路

2016-03-19 10:49:05 1732浏览量 回答数 1

1

回答

Javascript中的反向数组而不更改原始数组

2020-02-06 22:47:45 1220浏览量 回答数 1

1

回答

Javascript json数据与数组数据处理

2016-07-07 18:34:08 1795浏览量 回答数 1

2

回答

JavaScript 怎么对数组进行 回调操作 的不影响原数组?

2016-06-12 14:51:56 1637浏览量 回答数 2

1

回答

JavaScript 怎么对数组进行 回调操作 的不影响原数组?

2016-04-09 13:12:39 1681浏览量 回答数 1

1

回答

在JavaScript 怎么声明一个关联数组?

2016-04-09 15:51:28 2043浏览量 回答数 1

1

回答

如何用JavaScript批量提交多个数组?

2016-03-20 10:52:41 1739浏览量 回答数 1

1

回答

javascript中的数组,对象的使用

2016-03-20 12:45:39 1888浏览量 回答数 1

1

回答

javascript如何验证数组是否存在某元素

2016-03-19 11:32:27 1866浏览量 回答数 1

2

回答

javascript中如何将字符数组转为整型数组

2016-03-19 11:05:34 2652浏览量 回答数 2
+关注
文章
问答
问答排行榜
最热
最新
相关电子书
更多
Python第五讲——关于爬虫如何做js逆向的思路
立即下载
编程语言如何演化—— 以 JS 的 private 为例
立即下载
JS 语言在引擎级别的执行过程
立即下载