fix(nds): wrong 3d click detection
This commit is contained in:
@@ -274,12 +274,7 @@ const pressButton = (button: string) => {
|
|||||||
window.dispatchEvent(new KeyboardEvent("keydown", { key: `NDS_${button}` }));
|
window.dispatchEvent(new KeyboardEvent("keydown", { key: `NDS_${button}` }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = (event: MouseEvent) => {
|
const raycast = (event: MouseEvent) => {
|
||||||
if (!hasAnimated.value) {
|
|
||||||
animateIntro();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const domElement = renderer.instance.domElement;
|
const domElement = renderer.instance.domElement;
|
||||||
const rect = domElement.getBoundingClientRect();
|
const rect = domElement.getBoundingClientRect();
|
||||||
|
|
||||||
@@ -293,32 +288,50 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const intersects = raycaster.intersectObjects(model.children, true);
|
const intersects = raycaster.intersectObjects(model.children, true);
|
||||||
const intersection = intersects[0];
|
return intersects[0];
|
||||||
if (!intersection?.uv) return;
|
};
|
||||||
|
|
||||||
switch (intersection.object.name) {
|
const getScreenCanvas = (name: string) => {
|
||||||
case TOP_SCREEN:
|
if (name === TOP_SCREEN) return props.topScreenCanvas;
|
||||||
case BOTTOM_SCREEN: {
|
if (name === BOTTOM_SCREEN) return props.bottomScreenCanvas;
|
||||||
const canvas =
|
return null;
|
||||||
intersection.object.name === TOP_SCREEN
|
};
|
||||||
? props.topScreenCanvas
|
|
||||||
: props.bottomScreenCanvas;
|
|
||||||
|
|
||||||
if (!canvas) break;
|
const dispatchScreenEvent = (
|
||||||
|
type: string,
|
||||||
|
canvas: HTMLCanvasElement,
|
||||||
|
intersection: THREE.Intersection,
|
||||||
|
) => {
|
||||||
|
if (!intersection.uv) return;
|
||||||
|
|
||||||
const logicalX = (1 - intersection.uv.x) * LOGICAL_WIDTH;
|
const logicalX = (1 - intersection.uv.x) * LOGICAL_WIDTH;
|
||||||
const logicalY = (1 - intersection.uv.y) * LOGICAL_HEIGHT;
|
const logicalY = (1 - intersection.uv.y) * LOGICAL_HEIGHT;
|
||||||
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
const rect = canvas.getBoundingClientRect();
|
||||||
canvas.dispatchEvent(
|
canvas.dispatchEvent(
|
||||||
new MouseEvent("click", {
|
new MouseEvent(type, {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true,
|
cancelable: true,
|
||||||
clientX: (logicalX / LOGICAL_WIDTH) * rect.width + rect.left,
|
clientX: (logicalX / LOGICAL_WIDTH) * rect.width + rect.left,
|
||||||
clientY: (logicalY / LOGICAL_HEIGHT) * rect.height + rect.top,
|
clientY: (logicalY / LOGICAL_HEIGHT) * rect.height + rect.top,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseDown = (event: MouseEvent) => {
|
||||||
|
if (!hasAnimated.value) {
|
||||||
|
animateIntro();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const intersection = raycast(event);
|
||||||
|
if (!intersection?.uv) return;
|
||||||
|
|
||||||
|
switch (intersection.object.name) {
|
||||||
|
case TOP_SCREEN:
|
||||||
|
case BOTTOM_SCREEN: {
|
||||||
|
const canvas = getScreenCanvas(intersection.object.name);
|
||||||
|
if (canvas) dispatchScreenEvent("mousedown", canvas, intersection);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,6 +374,16 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClick = (event: MouseEvent) => {
|
||||||
|
if (!hasAnimated.value) return;
|
||||||
|
|
||||||
|
const intersection = raycast(event);
|
||||||
|
if (!intersection?.uv) return;
|
||||||
|
|
||||||
|
const canvas = getScreenCanvas(intersection.object.name);
|
||||||
|
if (canvas) dispatchScreenEvent("click", canvas, intersection);
|
||||||
|
};
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
if (mousePressedButton) {
|
if (mousePressedButton) {
|
||||||
physicalButtonsDown.delete(mousePressedButton);
|
physicalButtonsDown.delete(mousePressedButton);
|
||||||
@@ -377,14 +400,19 @@ onMounted(() => {
|
|||||||
app.ready = true;
|
app.ready = true;
|
||||||
|
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
renderer.instance.domElement.addEventListener("mousedown", handleClick);
|
renderer.instance.domElement.addEventListener("mousedown", handleMouseDown);
|
||||||
|
renderer.instance.domElement.addEventListener("click", handleClick);
|
||||||
renderer.instance.domElement.addEventListener("mouseup", handleMouseUp);
|
renderer.instance.domElement.addEventListener("mouseup", handleMouseUp);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
renderer.instance.domElement.removeEventListener("mousedown", handleClick);
|
renderer.instance.domElement.removeEventListener(
|
||||||
|
"mousedown",
|
||||||
|
handleMouseDown,
|
||||||
|
);
|
||||||
|
renderer.instance.domElement.removeEventListener("click", handleClick);
|
||||||
renderer.instance.domElement.removeEventListener("mouseup", handleMouseUp);
|
renderer.instance.domElement.removeEventListener("mouseup", handleMouseUp);
|
||||||
}
|
}
|
||||||
topScreenTexture?.dispose();
|
topScreenTexture?.dispose();
|
||||||
|
|||||||
Reference in New Issue
Block a user