mime-chat/src/modules/scrollView.ts
2021-02-15 09:26:36 -06:00

69 lines
1.7 KiB
TypeScript

import { ref, computed, onMounted, onUnmounted } from "vue";
/**
* handles visualization of view messages through
* vue transition callbacks and anime-js animations
*/
export default function useScrollView({ targetId }: { targetId: string }) {
const scroll = ref(0);
let scrollTarget: HTMLElement | SVGElement | null;
const targetHeight = ref(0);
let topBound: number;
const scrollStartHeight = 445;
const clampedScroll = computed(() => {
if (targetHeight.value === 0) { return 0; }
topBound = -targetHeight.value + 450;
return Math.max(topBound, Math.min(scroll.value, 0)) as number;
})
const scrollView = computed(() => {
if (clampedScroll.value === 0) {
scroll.value = 0;
} else if (clampedScroll.value === topBound) {
scroll.value = topBound;
}
return `0 ${clampedScroll.value} 350 500`;
});
const getHeight = () => {
if (scrollTarget) {
return scrollTarget.getBoundingClientRect().height as number;
}
}
const updateView = (verticalScroll: number) => {
if (scrollTarget) {
const heightResult = getHeight();
if (heightResult) {
// only scroll if renderer scrollStart
if (heightResult > scrollStartHeight) {
targetHeight.value = heightResult;
scroll.value += verticalScroll;
}
}
}
}
const scrollUpdate = (e: any): void => {
const verticalScroll = e.deltaY * 0.25;
updateView(verticalScroll);
}
onMounted(() => {
scrollTarget = document.getElementById(targetId);
if (scrollTarget) {
window.addEventListener("wheel", scrollUpdate);
}
});
onUnmounted(() => {
window.removeEventListener("wheel", scrollUpdate);
})
return {
scrollView
}
}