feat: useMouseWheel -> useScreenMouseWheel

This commit is contained in:
2025-11-21 21:01:46 +01:00
parent 02ee08b4b0
commit eda85b7435
4 changed files with 36 additions and 16 deletions

View File

@@ -88,7 +88,7 @@ useKeyDown((key) => {
} }
}); });
useMouseWheel((dy) => { useScreenMouseWheel((dy) => {
if (dy > 0) { if (dy > 0) {
scrollProjects("right"); scrollProjects("right");
} else if (dy < 0) { } else if (dy < 0) {

View File

@@ -4,6 +4,7 @@ const canvas = useTemplateRef("canvas");
const updateCallbacks = new Set<UpdateCallback>(); const updateCallbacks = new Set<UpdateCallback>();
const renderCallbacks = new Set<RenderCallback>(); const renderCallbacks = new Set<RenderCallback>();
const screenClickCallbacks = new Set<ScreenClickCallback>(); const screenClickCallbacks = new Set<ScreenClickCallback>();
const screenMouseWheelCallbacks = new Set<ScreenMouseWheelCallback>();
let ctx: CanvasRenderingContext2D | null = null; let ctx: CanvasRenderingContext2D | null = null;
let animationFrameId: number | null = null; let animationFrameId: number | null = null;
@@ -25,6 +26,13 @@ const registerScreenClickCallback = (callback: ScreenClickCallback) => {
return () => screenClickCallbacks.delete(callback); return () => screenClickCallbacks.delete(callback);
}; };
const registerScreenMouseWheelCallback = (
callback: ScreenMouseWheelCallback,
) => {
screenMouseWheelCallbacks.add(callback);
return () => screenMouseWheelCallbacks.delete(callback);
};
const handleCanvasClick = (event: MouseEvent) => { const handleCanvasClick = (event: MouseEvent) => {
if (!canvas.value) return; if (!canvas.value) return;
@@ -40,6 +48,12 @@ const handleCanvasClick = (event: MouseEvent) => {
} }
}; };
const handleCanvasWheel = (event: WheelEvent) => {
for (const callback of screenMouseWheelCallbacks) {
callback(event.deltaY, event.deltaX);
}
};
const renderFrame = (timestamp: number) => { const renderFrame = (timestamp: number) => {
if (!ctx) return; if (!ctx) return;
@@ -78,8 +92,10 @@ onMounted(() => {
provide("registerUpdateCallback", registerUpdateCallback); provide("registerUpdateCallback", registerUpdateCallback);
provide("registerRenderCallback", registerRenderCallback); provide("registerRenderCallback", registerRenderCallback);
provide("registerScreenClickCallback", registerScreenClickCallback); provide("registerScreenClickCallback", registerScreenClickCallback);
provide("registerScreenMouseWheelCallback", registerScreenMouseWheelCallback);
canvas.value.addEventListener("click", handleCanvasClick); canvas.value.addEventListener("click", handleCanvasClick);
canvas.value.addEventListener("wheel", handleCanvasWheel, { passive: true });
animationFrameId = requestAnimationFrame(renderFrame); animationFrameId = requestAnimationFrame(renderFrame);
}); });
@@ -91,6 +107,7 @@ onUnmounted(() => {
if (canvas.value) { if (canvas.value) {
canvas.value.removeEventListener("click", handleCanvasClick); canvas.value.removeEventListener("click", handleCanvasClick);
canvas.value.removeEventListener("wheel", handleCanvasWheel);
} }
}); });
</script> </script>

View File

@@ -1,15 +0,0 @@
export type MouseWheelCallback = (deltaY: number, deltaX: number) => void;
export const useMouseWheel = (callback: MouseWheelCallback) => {
const handleWheel = (event: WheelEvent) => {
callback(event.deltaY, event.deltaX);
};
onMounted(() => {
window.addEventListener("wheel", handleWheel, { passive: true });
});
onUnmounted(() => {
window.removeEventListener("wheel", handleWheel);
});
};

View File

@@ -0,0 +1,18 @@
export type ScreenMouseWheelCallback = (deltaY: number, deltaX: number) => void;
export const useScreenMouseWheel = (callback: ScreenMouseWheelCallback) => {
const registerScreenMouseWheelCallback = inject<
(callback: ScreenMouseWheelCallback) => () => void
>("registerScreenMouseWheelCallback");
onMounted(() => {
if (!registerScreenMouseWheelCallback) {
throw new Error(
"Missing registerScreenMouseWheelCallback - useScreenMouseWheel must be used within a Screen component",
);
}
const unregister = registerScreenMouseWheelCallback(callback);
onUnmounted(unregister);
});
};