简体   繁体   English

使用缓动功能滚动

[英]Scrolling with an easing function

I have written a function that when invoked, will scroll the page downwards in a smooth fashion. 我编写了一个函数,该函数在调用时将以平滑的方式向下滚动页面。

The problem is that the amount scrolled is not precise. 问题是滚动量不精确。 It can be off by one pixel or so depending on the distance scrolled and the duration of the scroll. 它可以偏移一个像素左右,具体取决于滚动的距离和滚动的持续时间。

Is there a better way to do this such that the scroll can move the exact number of desired pixels? 有没有更好的方法可以做到这一点,从而使滚动条可以移动所需像素的确切数量?

 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> 

could you do something like this to account for the last iteration? 您能做这样的事情来说明上一次迭代吗?

basically if toMove gets rounded down to 0, but distance hasnt been travelled yet, force it to do scroll one more? 基本上,如果toMove向下取整为0,但是距离尚未移动,是否要强制它再滚动一遍?

if(toMove > 0 || (toMove == 0 && travelled != distance) {
  window.scrollBy(0, (toMove ? toMove : 1));
  travelled += toMove;
}

I decided to modify the done logic to move any remaining distance: 我决定修改完成的逻辑以移动任何剩余距离:

// ...
if((1 - fractionDone) <= 0) {
  window.scrollBy(0, (distance - travelled)); // Scroll any remaining distance.
  return; // Done!
}
// ...

Which, I think, solves the issue. 我认为,这可以解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM