useScrollTo.ts 1.2 KB

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