48 lines
No EOL
1.3 KiB
TypeScript
48 lines
No EOL
1.3 KiB
TypeScript
import {ref, computed, onMounted} from "vue";
|
|
export default function useScroller({ targetId }: {targetId: string}) {
|
|
|
|
const scroll = ref(0);
|
|
let scrollTarget: HTMLElement | SVGElement | null;
|
|
const targetHeight = ref(0);
|
|
let topBound: number;
|
|
|
|
const clampedScroll = computed(() => {
|
|
const test = targetHeight.value;
|
|
if (test === 0) { return 0; }
|
|
topBound = -test + 440;
|
|
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`;
|
|
});
|
|
|
|
onMounted(() => {
|
|
scrollTarget = document.getElementById(targetId);
|
|
});
|
|
|
|
window.addEventListener(
|
|
"wheel",
|
|
(e) => {
|
|
if (scrollTarget) {
|
|
// get renderer height
|
|
targetHeight.value = scrollTarget.getBoundingClientRect().height;
|
|
// only scroll if renderer height is greater than main window
|
|
if (targetHeight.value > 500) {
|
|
scroll.value += e.deltaY * 0.25;
|
|
}
|
|
}
|
|
},
|
|
{ passive: true }
|
|
);
|
|
|
|
return {
|
|
scrollView
|
|
}
|
|
|
|
} |