JavaScript运动之缓冲运动
2017-05-10 21:28
295 查看
缓冲运动
逐渐变慢,最后停止距离越远,速度越大
速度由距离决定
速度 = (目标值 - 当前值)/ 缩放系数
例子:缓冲菜单
- Bug:速度取整
- 跟随页面滚动的缓冲侧边栏
1. 潜在问题:目标值不是整数时
速度和距离成正比
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> #div1 { width: 100px; height: 100px; background: red; position: absolute; left: 0; top: 50px; } #div2 { width: 1px; height: 300px; position: absolute; left: 300px; top: 0; background: black; } </style> </head> <body> <div id="div1"></div> <div id="div2"></div> <input type="button" value="Start" onclick="startMove()" /> <script type="text/javascript"> var oDiv = document.getElementById('div1'); function startMove() { setInterval(function() { //随着距离的减小,速度也越来越小,符合缓冲的要求,用距离(时刻变化)的十分之一 var speed = (300 - oDiv.offsetLeft) / 10; oDiv.style.left = oDiv.offsetLeft + speed + 'px'; document.title = oDiv.offsetLeft + ', ' + speed; }, 30); } </script> </body> </html>
##### 最后在title上发现“291, 0.9”,也就是物体向右缓冲运动到291px的位置停下,最后时刻有一刻距离还剩9px,速度也就是0.9px,然后滑动向着291.9px的目标前进,但是px是最小的单位,291.9px,计算机就认为是291px,所以,也就永远停在291的位置了,还到不了300的最终位置
Math
Math.ceil(3.2) ==> 4 Math.ceil(-9.7) ==> -9 Math.floor(5.98) ==> 5
[b]所以,speed采用ceil方法向上取整即可,最后能跑到300的位置,分毫不差[/b]
function startMove() { setInterval(function() { //随着距离的减小,速度也越来越小,符合缓冲的要求,用距离(时刻变化)的十分之一 var speed = (300 - oDiv.offsetLeft) / 10; speed = Math.ceil(speed);//划重点 oDiv.style.left = oDiv.offsetLeft + speed + 'px'; document.title = oDiv.offsetLeft + ', ' + speed; }, 30); }
这样就完了吗?没有!如果物体左移,也就是比如把div1的left的初始left由0 –> 600,那么,依旧不能分毫无差,最后看title为“309, 0”,实际上,速度为-0.9,(下一刻向着目标308.1px的位置移动),此时Math.ceil()已经不好用了,得用Math.floor();
#div1 { width: 100px; height: 100px; background: red; position: absolute; left: 600px;/*0 --> 600*/ top: 50px; } function startMove() { setInterval(function() { var speed = (300 - oDiv.offsetLeft) / 10; speed = Math.floor(speed);//划重点 oDiv.style.left = oDiv.offsetLeft + speed + 'px'; document.title = oDiv.offsetLeft + ', ' + speed; }, 30); }
综上所述:如果正向移动,为了让物体迈过那个不足1的坎,要帮助小数颠颠脚够着更大的整数(0.2 –>1,ceil),如果负向移动,为了让物体迈过不足-1的坎,要帮小数颠颠脚够着更小(绝对值更大)的整数(-0.1 –> -1, floor)
offsetWidth = width + border + padding; offsetWidth = height + border + padding; offsetWidth = width + border + padding;
function startMove() { setInterval(function() { var speed = (300 - oDiv.offsetLeft) / 10; speed ebca = speed > 0 ? Math.ceil(speed) : Match.floor(speed); oDiv.style.left = oDiv.offsetLeft + speed + 'px'; document.title = oDiv.offsetLeft + ', ' + speed; }, 30); }
总结:但凡是用了缓冲运动的一定要记得速度取整,缓冲也就是速度不停的变化。
缓冲菜单
要求:在右下角有个红色div,无论浏览器怎么滚动,始终落脚在右下角注意几个概念: offsetWidth = width + border + padding; offsetHeight = width + border + padding; document.documentElement.scrollHeight: 内容可视区域的高度,真正展示网页内容的高度,客户端的界面要跑除,如果你用鼠标调节浏览器窗口的大小,那么这个值会变化。 document.documentElement.scrollHeight:就是3500px,上面已经设置了 网页被卷去的高:document.body.scrollTop 兼容: var top = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
综上所述: 在我们要获取文档实际高度时,最好用document.documentElement.scrollHeight 在我们要获取视口实际高度时,用document.documentElement.clientHeight
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> * { padding: 0; margin: 0; } #div1 { width: 100px; height: 150px; background: red; position: absolute; bottom: 0; right: 0; border: 3px solid blue; padding: 20px; } </style> </head> <body style="height: 3500px;"> <div id="div1"></div> <div id="div2"></div> <script type="text/javascript"> window.onscroll = function() { var oDiv = document.getElementById('div1'); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + 'px'; }; </script> </body> </html>
上面这段代码就可以让红色物体div紧紧 ‘fix’到页面的右下角,但是,你滚动网页的时候发现div为了努力的紧跟右下角,很费力的在抖动,看起来很不自然,为了看起来自然,需要自写一个运动框架,不让他硬生生的跟着走,而是慢慢的缓缓的缓冲运动。
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> * { padding: 0; margin: 0; } #div1 { width: 100px; height: 150px; background: red; position: absolute; bottom: 0; right: 0; border: 3px solid blue; padding: 20px; } </style> </head> <body style="height: 3500px;"> <div id="div1"></div> <div id="div2"></div> <script type="text/javascript"> window.onscroll = function() { var oDiv = document.getElementById('div1'); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + 'px'; startMove(document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop); }; var timer = null; function startMove(iTarget) { var oDiv = document.getElementById('div1'); clearInterval(timer); timer = setInterval(function() { var speed = (iTarget - oDiv.offsetTop)/6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (oDiv.offsetTop == iTarget) { clearInterval(timer); } else { oDiv.style.top = oDiv.offsetTop + speed + 'px'; } }, 30); } </script> </body> </html>
对联悬浮框
不同上边案例悬浮在右下角,而是‘fix’到右边正中间位置<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> * { padding: 0; margin: 0; } #div1 { width: 100px; height: 150px; background: red; position: absolute; bottom: 0; right: 0; border: 3px solid blue; padding: 20px; } </style> </head> <body style="height: 3500px;"> <div id="div1"></div> <div id="div2"></div> <script type="text/javascript"> window.onscroll = function() { var oDiv = document.getElementById('div1'); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //其实仅仅就是参数iTarget的计算变了一下 startMove((document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop); }; var timer = null; function startMove(iTarget) { var oDiv = document.getElementById('div1'); clearInterval(timer); timer = setInterval(function() { var speed = (iTarget - oDiv.offsetTop)/6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (oDiv.offsetTop == iTarget) { clearInterval(timer); } else { oDiv.style.top = oDiv.offsetTop + speed + 'px'; } }, 30); } </script> </body> </html>
代码写完了,发现红色div在右边中间以很小的振幅在不同的抖动,问题就出在除以2这里,除以2就可能出现小数的可能性
startMove((document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop); 改为: startMove(parseInt(document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop));
相关文章推荐
- JavaScript缓冲运动实现方法(2则示例)
- JavaScript 高级课程之缓冲/多个DIV运动框架
- 40、JavaScript的运动----缓冲运动
- JavaScript缓冲运动实现方法(2则示例)
- javascript每日一练(十)——运动二:缓冲运动
- JavaScript 动画之缓冲运动
- javascript 运动缓冲效果
- javascript 缓冲运动框架的实现
- JavaScript动画2-缓冲运动
- JavaScript中的匀速运动和变速(缓冲)运动详细介绍
- JavaScript中的匀速运动和变速(缓冲)运动详细介绍
- JavaScript 高级课程之缓冲+多个DIV运动框架实现 + 透明度
- 用javascript实现缓冲运动
- JavaScript动画篇之缓冲运动
- Javascript运动概念1——缓冲运动、匀速运动、运动框架
- JavaScript中的匀速运动和变速(缓冲)运动
- JavaScript缓冲运动之防抖动
- javascript运动基础——摩擦和缓冲
- JavaScript实现跟随滚动缓冲运动广告框