feat: implement useScreenClick
This commit is contained in:
@@ -26,6 +26,24 @@ const nextBottomButton = ref<"downloadPlay" | "pictochat">("pictochat");
|
|||||||
|
|
||||||
const selectorPosition = computed(() => BUTTONS_CONFIG[selectedButton.value]);
|
const selectorPosition = computed(() => BUTTONS_CONFIG[selectedButton.value]);
|
||||||
|
|
||||||
|
useScreenClick((x: number, y: number) => {
|
||||||
|
for (const [buttonName, config] of Object.entries(BUTTONS_CONFIG)) {
|
||||||
|
if (
|
||||||
|
x >= config.sx &&
|
||||||
|
x <= config.sx + config.sw &&
|
||||||
|
y >= config.sy &&
|
||||||
|
y <= config.sy + config.sh
|
||||||
|
) {
|
||||||
|
selectedButton.value = buttonName as ButtonType;
|
||||||
|
|
||||||
|
if (buttonName === "pictochat" || buttonName === "downloadPlay") {
|
||||||
|
nextBottomButton.value = buttonName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const handleKeyPress = (event: KeyboardEvent) => {
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
|
|||||||
@@ -3,6 +3,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>();
|
||||||
|
|
||||||
let ctx: CanvasRenderingContext2D | null = null;
|
let ctx: CanvasRenderingContext2D | null = null;
|
||||||
let animationFrameId: number | null = null;
|
let animationFrameId: number | null = null;
|
||||||
@@ -19,6 +20,26 @@ const registerRenderCallback = (callback: RenderCallback) => {
|
|||||||
return () => renderCallbacks.delete(callback);
|
return () => renderCallbacks.delete(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const registerScreenClickCallback = (callback: ScreenClickCallback) => {
|
||||||
|
screenClickCallbacks.add(callback);
|
||||||
|
return () => screenClickCallbacks.delete(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCanvasClick = (event: MouseEvent) => {
|
||||||
|
if (!canvas.value) return;
|
||||||
|
|
||||||
|
const rect = canvas.value.getBoundingClientRect();
|
||||||
|
const scaleX = SCREEN_WIDTH / rect.width;
|
||||||
|
const scaleY = SCREEN_HEIGHT / rect.height;
|
||||||
|
|
||||||
|
const x = (event.clientX - rect.left) * scaleX;
|
||||||
|
const y = (event.clientY - rect.top) * scaleY;
|
||||||
|
|
||||||
|
for (const callback of screenClickCallbacks) {
|
||||||
|
callback(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const renderFrame = (timestamp: number) => {
|
const renderFrame = (timestamp: number) => {
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
|
||||||
@@ -56,6 +77,9 @@ onMounted(() => {
|
|||||||
|
|
||||||
provide("registerUpdateCallback", registerUpdateCallback);
|
provide("registerUpdateCallback", registerUpdateCallback);
|
||||||
provide("registerRenderCallback", registerRenderCallback);
|
provide("registerRenderCallback", registerRenderCallback);
|
||||||
|
provide("registerScreenClickCallback", registerScreenClickCallback);
|
||||||
|
|
||||||
|
canvas.value.addEventListener("click", handleCanvasClick);
|
||||||
|
|
||||||
animationFrameId = requestAnimationFrame(renderFrame);
|
animationFrameId = requestAnimationFrame(renderFrame);
|
||||||
});
|
});
|
||||||
@@ -64,6 +88,10 @@ onUnmounted(() => {
|
|||||||
if (animationFrameId !== null) {
|
if (animationFrameId !== null) {
|
||||||
cancelAnimationFrame(animationFrameId);
|
cancelAnimationFrame(animationFrameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canvas.value) {
|
||||||
|
canvas.value.removeEventListener("click", handleCanvasClick);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
18
app/composables/useScreenClick.ts
Normal file
18
app/composables/useScreenClick.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export type ScreenClickCallback = (x: number, y: number) => void;
|
||||||
|
|
||||||
|
export const useScreenClick = (callback: ScreenClickCallback) => {
|
||||||
|
const registerScreenClickCallback = inject<
|
||||||
|
(callback: ScreenClickCallback) => () => void
|
||||||
|
>("registerScreenClickCallback");
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!registerScreenClickCallback) {
|
||||||
|
throw new Error(
|
||||||
|
"Missing registerScreenClickCallback - useScreenClick must be used within a Screen component",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unregister = registerScreenClickCallback(callback);
|
||||||
|
onUnmounted(unregister);
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user