[英]Scrolling with an easing function
我编写了一个函数,该函数在调用时将以平滑的方式向下滚动页面。
问题是滚动量不精确。 它可以偏移一个像素左右,具体取决于滚动的距离和滚动的持续时间。
有没有更好的方法可以做到这一点,从而使滚动条可以移动所需像素的确切数量?
const EASING = BezierEasing(0, .1, .1, 1); // Example values. const DURATION = 1000; // ms. document.addEventListener('DOMContentLoaded', () => { document.querySelector('#foo') .addEventListener('click', onClick, false); }); function onClick(e) { scroll(400); // px. e.preventDefault(); return false; } function scroll(distance) { var start, travelled, html; start = performance.now(); travelled = 0; html = document.querySelector('html'); (function move(now) { var fractionDone, dy, toMove; fractionDone = (now-start) / DURATION; if((1 - fractionDone) <= 0) { return; // Done! } if(window.scrollY + window.innerHeight === html.offsetHeight) { return; // At bottom of page. } dy = ((EASING.get(fractionDone)) * distance); toMove = Math.floor((dy - travelled)); // `scrollBy` only accepts integers. if(toMove > 0) { window.scrollBy(0, toMove); travelled += toMove; } requestAnimationFrame(move); }(start)); }
<!DOCTYPE html> <html> <head> <script src="https://rawgit.com/gre/bezier-easing/master/build.js"></script> </head> <body> <a href id="foo">Click Me!</a> <script> /* print some numbers to the DOM to help visualize the scrolling */ var body = document.querySelector('body'); for(var x = 0; x < 50; x++) { var div = document.createElement("div"); var text = document.createTextNode(x); div.appendChild(text); body.appendChild(div); } </script> </body> </html>
您能做这样的事情来说明上一次迭代吗?
基本上,如果toMove向下取整为0,但是距离尚未移动,是否要强制它再滚动一遍?
if(toMove > 0 || (toMove == 0 && travelled != distance) {
window.scrollBy(0, (toMove ? toMove : 1));
travelled += toMove;
}
我决定修改完成的逻辑以移动任何剩余距离:
// ...
if((1 - fractionDone) <= 0) {
window.scrollBy(0, (distance - travelled)); // Scroll any remaining distance.
return; // Done!
}
// ...
我认为,这可以解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.