1
0

useScrollTo.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { isFunction, isUnDef } from '/@/utils/is';
  2. import { ref, unref } from 'vue';
  3. export interface ScrollToParams {
  4. el: any;
  5. to: number;
  6. duration?: number;
  7. callback?: () => any;
  8. }
  9. const easeInOutQuad = (t: number, b: number, c: number, d: number) => {
  10. t /= d / 2;
  11. if (t < 1) {
  12. return (c / 2) * t * t + b;
  13. }
  14. t--;
  15. return (-c / 2) * (t * (t - 2) - 1) + b;
  16. };
  17. const move = (el: HTMLElement, amount: number) => {
  18. el.scrollTop = amount;
  19. };
  20. const position = (el: HTMLElement) => {
  21. return el.scrollTop;
  22. };
  23. export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams) {
  24. const isActiveRef = ref(false);
  25. const start = position(el);
  26. const change = to - start;
  27. const increment = 20;
  28. let currentTime = 0;
  29. duration = isUnDef(duration) ? 500 : duration;
  30. const animateScroll = function () {
  31. if (!unref(isActiveRef)) {
  32. return;
  33. }
  34. currentTime += increment;
  35. const val = easeInOutQuad(currentTime, start, change, duration);
  36. move(el, val);
  37. if (currentTime < duration && unref(isActiveRef)) {
  38. requestAnimationFrame(animateScroll);
  39. } else {
  40. if (callback && isFunction(callback)) {
  41. callback();
  42. }
  43. }
  44. };
  45. const run = () => {
  46. isActiveRef.value = true;
  47. animateScroll();
  48. };
  49. const stop = () => {
  50. isActiveRef.value = false;
  51. };
  52. return { start: run, stop };
  53. }