当前位置: 首页 > 编程笔记 >

Javascript动画的实现原理浅析

程振濂
2023-03-14
本文向大家介绍Javascript动画的实现原理浅析,包括了Javascript动画的实现原理浅析的使用技巧和注意事项,需要的朋友参考一下

假设有这样一个动画功能需求:把一个div的宽度从100px变化到200px。写出来的代码可能是这样的:


<div id="test1" style="width: 100px; height: 100px; background: blue; color: white;"></div>

function animate1(element, endValue, duration) {

    var startTime = new Date(),

        startValue = parseInt(element.style.width),

        step = 1;

    

    var timerId = setInterval(function() {

        var nextValue = parseInt(element.style.width) + step;

        element.style.width = nextValue + 'px';

        if (nextValue >= endValue) {

            clearInterval(timerId);

            // 显示动画耗时

            element.innerHTML = new Date - startTime;

        }

    }, duration / (endValue - startValue) * step);

}

animate1(document.getElementById('test1'), 200, 1000);


原理是每隔一定时间增加1px,一直到200px为止。然而,动画结束后显示的耗时却不止1s(一般是1.5s左右)。究其原因,是因为setInterval并不能严格保证执行间隔。

有没有更好的做法呢?下面先来看一道小学数学题:


A楼和B楼相距100米,一个人匀速从A楼走到B楼,走了5分钟到达目的地,问第3分钟时他距离A楼多远?


匀速运动中计算某个时刻路程的计算公式为:路程 * 当前时间 / 时间 。所以答案应为 100 * 3 / 5 = 60 。

这道题带来的启发是,某个时刻的路程是可以通过特定公式计算出来的。同理,动画过程中某个时刻的值也可以通过公式计算出来,而不是累加得出:


<div id="test2" style="width: 100px; height: 100px; background: red; color: white;"></div>

function animate2(element, endValue, duration) {

    var startTime = new Date(),

        startValue = parseInt(element.style.width);

    var timerId = setInterval(function() {         var percentage = (new Date - startTime) / duration;

        var stepValue = startValue + (endValue - startValue) * percentage;         element.style.width = stepValue + 'px';

        if (percentage >= 1) {             clearInterval(timerId);             element.innerHTML = new Date - startTime;         }     }, 13); }

animate2(document.getElementById('test2'), 200, 1000);

这样改良之后,可以看到动画执行耗时最多只会有10几ms的误差。但是问题还没完全解决,在浏览器开发工具中检查test2元素可以发现,test2的最终宽度可能不止200px。仔细检查animate2函数的代码可以发现:

1.percentage的值可能大于1,可以通过Math.min限制最大值解决。
2.即使保证了percentage的值不大于1,只要endValue或startValue为小数,(endValue - startValue) * percentage的值也可能产生误差,因为Javascript小数运算的精度不够。其实我们要保证的只是最终值的准确性,所以在percentage为1的时候,直接使用endValue即可。

于是,animate2函数的代码修改为:


function animate2(element, endValue, duration) {

    var startTime = new Date(),

        startValue = parseInt(element.style.width);

    var timerId = setInterval(function() {         // 保证百分率不大于1         var percentage = Math.min(1, (new Date - startTime) / duration);

        var stepValue;         if (percentage >= 1) {             // 保证最终值的准确性             stepValue = endValue;         } else {             stepValue = startValue + (endValue - startValue) * percentage;         }         element.style.width = stepValue + 'px';

        if (percentage >= 1) {             clearInterval(timerId);             element.innerHTML = new Date - startTime;         }     }, 13); }

还有最后一个疑问:setInterval的间隔为何设为13ms?原因是当下显示器的刷新率一般不超过75Hz(即每秒刷新75次,也就是每隔约13ms刷新一次),把间隔跟刷新率同步效果更好。

 类似资料:
  • 本文向大家介绍浅析JavaScript动画模拟拖拽原理,包括了浅析JavaScript动画模拟拖拽原理的使用技巧和注意事项,需要的朋友参考一下 模拟拖拽的原理: x1等于div.offsetLeft y1等于div.offsetTop x2等于ev.clientX(ev表示event事件) y2等于ev.clientY 当我们在方块上按下鼠标的时候,x2-x1即可确定。移动鼠标之后,我们用鼠标当前

  • 本文向大家介绍浅析JavaScript动画,包括了浅析JavaScript动画的使用技巧和注意事项,需要的朋友参考一下 今天,小学生以自己浅薄的见地,在前辈大能的基础上写这篇文章,希望给大家打开一扇窥探JavaScript(以下简称JS)动画的窗户。 JS如何制造出动画效果?   结合浏览器提供的 setInterval 或 setTimeout API,高频改变DOM元素的一些属性,即可创造一个

  • 本文向大家介绍浅析vue中的MVVM实现原理,包括了浅析vue中的MVVM实现原理的使用技巧和注意事项,需要的朋友参考一下 现成MVVM 菜单教程 视图影响数据 数据影响视图 项目构架 mvvm.html mvvm.js compile把dom节点,放在内存中操作(到35分钟) 分类元素节点和文本节点(52分钟) 元素节点 文本节点 把data中的数据,显示在视图上(到1:16分) v-model

  • 本文向大家介绍javascript实现时钟动画,包括了javascript实现时钟动画的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了javascript实现时钟动画的具体代码,供大家参考,具体内容如下 效果图: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍浅谈vuejs实现数据驱动视图原理,包括了浅谈vuejs实现数据驱动视图原理的使用技巧和注意事项,需要的朋友参考一下 什么是数据驱动 数据驱动是vuejs最大的特点。在vuejs中,所谓的数据驱动就是当数据发生变化的时候,用户界面发生相应的变化,开发者不需要手动的去修改dom。 比如说我们点击一个button,需要元素的文本进行是和否的切换。在jquery刀耕火种的年代中,对于页面的

  • 我想写个动画。比如说鼠标向上滚动,一个div往上运动。当我鼠标向下的时候,div往下运动。 有没有这种动画库?我以前的做法是判断滚动方向。然后分别执行不同的动画函数。当然了我的一个动画里面,肯定是包含好几个运动元素的。