| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- import { isFunction, isUnDef } from '/@/utils/is';
- import { ref, unref } from 'vue';
- export interface ScrollToParams {
- el: any;
- to: number;
- duration?: number;
- callback?: () => any;
- }
- const 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;
- };
- const move = (el: HTMLElement, amount: number) => {
- el.scrollTop = amount;
- };
- const position = (el: HTMLElement) => {
- return el.scrollTop;
- };
- export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams) {
- const isActiveRef = ref(false);
- const start = position(el);
- const change = to - start;
- const increment = 20;
- let currentTime = 0;
- duration = isUnDef(duration) ? 500 : duration;
- 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 && isFunction(callback)) {
- callback();
- }
- }
- };
- const run = () => {
- isActiveRef.value = true;
- animateScroll();
- };
- const stop = () => {
- isActiveRef.value = false;
- };
- return { start: run, stop };
- }
|