scroll-to.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. const easeInOutQuad = (t: number, b: number, c: number, d: number) => {
  2. t /= d / 2;
  3. if (t < 1) {
  4. return (c / 2) * t * t + b;
  5. }
  6. t--;
  7. return (-c / 2) * (t * (t - 2) - 1) + b;
  8. };
  9. // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
  10. const requestAnimFrame = (function () {
  11. return (
  12. window.requestAnimationFrame ||
  13. (window as any).webkitRequestAnimationFrame ||
  14. (window as any).mozRequestAnimationFrame ||
  15. function (callback) {
  16. window.setTimeout(callback, 1000 / 60);
  17. }
  18. );
  19. })();
  20. /**
  21. * Because it's so fucking difficult to detect the scrolling element, just move them all
  22. * @param {number} amount
  23. */
  24. const move = (amount: number) => {
  25. document.documentElement.scrollTop = amount;
  26. (document.body.parentNode as HTMLElement).scrollTop = amount;
  27. document.body.scrollTop = amount;
  28. };
  29. const position = () => {
  30. return document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop;
  31. };
  32. /**
  33. * @param {number} to
  34. * @param {number} duration
  35. * @param {Function} callback
  36. */
  37. export const scrollTo = (to: number, duration: number, callback?: any) => {
  38. const start = position();
  39. const change = to - start;
  40. const increment = 20;
  41. let currentTime = 0;
  42. duration = typeof duration === 'undefined' ? 500 : duration;
  43. const animateScroll = function () {
  44. // increment the time
  45. currentTime += increment;
  46. // find the value with the quadratic in-out easing function
  47. const val = easeInOutQuad(currentTime, start, change, duration);
  48. // move the document.body
  49. move(val);
  50. // do the animation unless its over
  51. if (currentTime < duration) {
  52. requestAnimFrame(animateScroll);
  53. } else {
  54. if (callback && typeof callback === 'function') {
  55. // the animation is done so lets callback
  56. callback();
  57. }
  58. }
  59. };
  60. animateScroll();
  61. };