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 } }