feat(nds): dispatch events to screens from the nds itself
This commit is contained in:
@@ -8,11 +8,6 @@ const props = defineProps<{
|
|||||||
bottomScreenCanvas: HTMLCanvasElement | null;
|
bottomScreenCanvas: HTMLCanvasElement | null;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
topScreenClick: [x: number, y: number];
|
|
||||||
bottomScreenClick: [x: number, y: number];
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const { state: model } = useLoader(
|
const { state: model } = useLoader(
|
||||||
GLTFLoader,
|
GLTFLoader,
|
||||||
"/models/nintendo-ds/scene.gltf",
|
"/models/nintendo-ds/scene.gltf",
|
||||||
@@ -166,17 +161,32 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
switch (intersection.object.name) {
|
switch (intersection.object.name) {
|
||||||
case TOP_SCREEN:
|
case TOP_SCREEN:
|
||||||
case BOTTOM_SCREEN: {
|
case BOTTOM_SCREEN: {
|
||||||
|
const canvas =
|
||||||
|
intersection.object.name === TOP_SCREEN
|
||||||
|
? props.topScreenCanvas
|
||||||
|
: props.bottomScreenCanvas;
|
||||||
|
|
||||||
|
if (!canvas) break;
|
||||||
|
|
||||||
const x = Math.floor(intersection.uv.x * 256);
|
const x = Math.floor(intersection.uv.x * 256);
|
||||||
|
let y: number;
|
||||||
|
|
||||||
if (intersection.object.name === TOP_SCREEN) {
|
if (intersection.object.name === TOP_SCREEN) {
|
||||||
const y = Math.floor(intersection.uv.y * (1024 / 404) * 192);
|
y = Math.floor(intersection.uv.y * (1024 / 404) * 192);
|
||||||
emit("topScreenClick", x, y);
|
} else {
|
||||||
} else if (intersection.object.name === BOTTOM_SCREEN) {
|
y = Math.floor(192 - (1 - intersection.uv.y) * (1024 / 532) * 192);
|
||||||
const y = Math.floor(
|
|
||||||
192 - (1 - intersection.uv.y) * (1024 / 532) * 192,
|
|
||||||
);
|
|
||||||
emit("bottomScreenClick", x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
canvas.dispatchEvent(
|
||||||
|
new MouseEvent("click", {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
clientX: (x / 256) * rect.width + rect.left,
|
||||||
|
clientY: (y / 192) * rect.height + rect.top,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { OrbitControls } from "@tresjs/cientos";
|
import { OrbitControls } from "@tresjs/cientos";
|
||||||
|
import type { Screen as NDSScreen } from "#components";
|
||||||
|
|
||||||
|
type ScreenInstance = InstanceType<typeof NDSScreen>;
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const screen = computed(() => route.query.screen as string | undefined);
|
const screen = computed(() => route.query.screen as string | undefined);
|
||||||
|
|
||||||
const topScreen = useTemplateRef("topScreen");
|
const topScreen = useTemplateRef<ScreenInstance>("topScreen");
|
||||||
const bottomScreen = useTemplateRef("bottomScreen");
|
const bottomScreen = useTemplateRef<ScreenInstance>("bottomScreen");
|
||||||
|
|
||||||
const topScreenCanvas = computed(() => topScreen.value?.canvas ?? null);
|
const topScreenCanvas = computed(() => topScreen.value?.canvas ?? null);
|
||||||
const bottomScreenCanvas = computed(() => bottomScreen.value?.canvas ?? null);
|
const bottomScreenCanvas = computed(() => bottomScreen.value?.canvas ?? null);
|
||||||
|
|
||||||
const handleScreenClick = (
|
|
||||||
canvas: HTMLCanvasElement | null,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
) => {
|
|
||||||
if (!canvas) return;
|
|
||||||
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
|
||||||
const clickEvent = new MouseEvent("click", {
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
clientX: (x / SCREEN_WIDTH) * rect.width + rect.left,
|
|
||||||
clientY: (y / SCREEN_HEIGHT) * rect.height + rect.top,
|
|
||||||
});
|
|
||||||
canvas.dispatchEvent(clickEvent);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -41,10 +27,6 @@ const handleScreenClick = (
|
|||||||
v-if="topScreenCanvas && bottomScreenCanvas"
|
v-if="topScreenCanvas && bottomScreenCanvas"
|
||||||
:top-screen-canvas="topScreenCanvas"
|
:top-screen-canvas="topScreenCanvas"
|
||||||
:bottom-screen-canvas="bottomScreenCanvas"
|
:bottom-screen-canvas="bottomScreenCanvas"
|
||||||
@top-screen-click="(x, y) => handleScreenClick(topScreenCanvas, x, y)"
|
|
||||||
@bottom-screen-click="
|
|
||||||
(x, y) => handleScreenClick(bottomScreenCanvas, x, y)
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</TresCanvas>
|
</TresCanvas>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user