vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
38 lines
1.3 KiB
38 lines
1.3 KiB
import raf from './raf'; |
|
import getScroll, { isWindow } from './getScroll'; |
|
import { easeInOutCubic } from './easings'; |
|
|
|
interface ScrollToOptions { |
|
/** Scroll container, default as window */ |
|
getContainer?: () => HTMLElement | Window | Document; |
|
/** Scroll end callback */ |
|
callback?: () => any; |
|
/** Animation duration, default as 450 */ |
|
duration?: number; |
|
} |
|
|
|
export default function scrollTo(y: number, options: ScrollToOptions = {}) { |
|
const { getContainer = () => window, callback, duration = 450 } = options; |
|
const container = getContainer(); |
|
const scrollTop = getScroll(container, true); |
|
const startTime = Date.now(); |
|
|
|
const frameFunc = () => { |
|
const timestamp = Date.now(); |
|
const time = timestamp - startTime; |
|
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration); |
|
if (isWindow(container)) { |
|
(container as Window).scrollTo(window.pageXOffset, nextScrollTop); |
|
} else if (container instanceof HTMLDocument || container.constructor.name === 'HTMLDocument') { |
|
(container as HTMLDocument).documentElement.scrollTop = nextScrollTop; |
|
} else { |
|
(container as HTMLElement).scrollTop = nextScrollTop; |
|
} |
|
if (time < duration) { |
|
raf(frameFunc); |
|
} else if (typeof callback === 'function') { |
|
callback(); |
|
} |
|
}; |
|
raf(frameFunc); |
|
}
|
|
|