123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import { shallowRef, unref } from 'vue';
- interface UseScrollToOptions {
- el: any;
- to: number;
- duration?: number;
- callback?: () => any;
- }
- function easeInOutQuad(t: number, b: number, c: number, d: number) {
- t /= d / 2;
- if (t < 1) {
- return (c / 2) * t * t + b;
- }
- t--;
- return (-c / 2) * (t * (t - 2) - 1) + b;
- }
- function move(el: HTMLElement, amount: number) {
- el.scrollTop = amount;
- }
- const position = (el: HTMLElement) => {
- return el.scrollTop;
- };
- function useScrollTo({ el, to, duration = 500, callback }: UseScrollToOptions) {
- const isActiveRef = shallowRef(false);
- const start = position(el);
- const change = to - start;
- const increment = 20;
- let currentTime = 0;
- const animateScroll = function () {
- if (!unref(isActiveRef)) {
- return;
- }
- currentTime += increment;
- const val = easeInOutQuad(currentTime, start, change, duration);
- move(el, val);
- if (currentTime < duration && unref(isActiveRef)) {
- requestAnimationFrame(animateScroll);
- } else {
- if (callback && typeof callback === 'function') {
- callback();
- }
- }
- };
- const run = () => {
- isActiveRef.value = true;
- animateScroll();
- };
- const stop = () => {
- isActiveRef.value = false;
- };
- return { start: run, stop };
- }
- export { useScrollTo, type UseScrollToOptions };
|