Files
frontend-elite-data-analysis/src/pages/admin/ui/chat/StickyScroll.ts
T
2022-11-30 13:30:02 +08:00

53 lines
1.4 KiB
TypeScript

import { Directive, DirectiveBinding } from '@vue/runtime-core'
const directive: Directive = {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
const duration = binding.value.duration || 500
const isAnimated = binding.value.animate
const animateScroll = (duration: number) => {
const start = el.scrollTop
const end = el.scrollHeight
const change = end - start
const increment = 20
function easeInOut(currentTime: number, start: number, change: number, duration: number) {
currentTime /= duration / 2
if (currentTime < 1) {
return (change / 2) * currentTime * currentTime + start
}
currentTime -= 1
return (-change / 2) * (currentTime * (currentTime - 2) - 1) + start
}
function animate(elapsedTime: number) {
elapsedTime += increment
const position = easeInOut(elapsedTime, start, change, duration)
el.scrollTop = position
if (elapsedTime < duration) {
setTimeout(() => {
animate(elapsedTime)
}, increment)
}
}
animate(0)
}
const scrollToBottom = () => {
if (isAnimated) {
animateScroll(duration)
} else {
el.scrollTop = el.scrollHeight
}
}
const observer = new MutationObserver(scrollToBottom)
const config = { childList: true }
observer.observe(el, config)
},
}
export default directive