最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

Javascript动画的实现原理浅析_javascript技巧

来源:懂视网 责编:小采 时间:2020-11-27 21:35:05
文档

Javascript动画的实现原理浅析_javascript技巧

Javascript动画的实现原理浅析_javascript技巧:假设有这样一个动画功能需求:把一个div的宽度从100px变化到200px。写出来的代码可能是这样的: 代码如下: function animate1(element, endValue, duration) { var startTime = new Date(), startValue = parseInt(
推荐度:
导读Javascript动画的实现原理浅析_javascript技巧:假设有这样一个动画功能需求:把一个div的宽度从100px变化到200px。写出来的代码可能是这样的: 代码如下: function animate1(element, endValue, duration) { var startTime = new Date(), startValue = parseInt(

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

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 。

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

代码如下:

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刷新一次),把间隔跟刷新率同步效果更好。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

Javascript动画的实现原理浅析_javascript技巧

Javascript动画的实现原理浅析_javascript技巧:假设有这样一个动画功能需求:把一个div的宽度从100px变化到200px。写出来的代码可能是这样的: 代码如下: function animate1(element, endValue, duration) { var startTime = new Date(), startValue = parseInt(
推荐度:
标签: js javascript 动画的
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top