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}` }));
|
||||
};
|
||||
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
if (!hasAnimated.value) {
|
||||
animateIntro();
|
||||
return;
|
||||
}
|
||||
|
||||
const raycast = (event: MouseEvent) => {
|
||||
const domElement = renderer.instance.domElement;
|
||||
const rect = domElement.getBoundingClientRect();
|
||||
|
||||
@@ -293,32 +288,50 @@ const handleClick = (event: MouseEvent) => {
|
||||
);
|
||||
|
||||
const intersects = raycaster.intersectObjects(model.children, true);
|
||||
const intersection = intersects[0];
|
||||
return intersects[0];
|
||||
};
|
||||
|
||||
const getScreenCanvas = (name: string) => {
|
||||
if (name === TOP_SCREEN) return props.topScreenCanvas;
|
||||
if (name === BOTTOM_SCREEN) return props.bottomScreenCanvas;
|
||||
return null;
|
||||
};
|
||||
|
||||
const dispatchScreenEvent = (
|
||||
type: string,
|
||||
canvas: HTMLCanvasElement,
|
||||
intersection: THREE.Intersection,
|
||||
) => {
|
||||
if (!intersection.uv) return;
|
||||
|
||||
const logicalX = (1 - intersection.uv.x) * LOGICAL_WIDTH;
|
||||
const logicalY = (1 - intersection.uv.y) * LOGICAL_HEIGHT;
|
||||
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
canvas.dispatchEvent(
|
||||
new MouseEvent(type, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: (logicalX / LOGICAL_WIDTH) * rect.width + rect.left,
|
||||
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 =
|
||||
intersection.object.name === TOP_SCREEN
|
||||
? props.topScreenCanvas
|
||||
: props.bottomScreenCanvas;
|
||||
|
||||
if (!canvas) break;
|
||||
|
||||
const logicalX = (1 - intersection.uv.x) * LOGICAL_WIDTH;
|
||||
const logicalY = (1 - intersection.uv.y) * LOGICAL_HEIGHT;
|
||||
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
canvas.dispatchEvent(
|
||||
new MouseEvent("click", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: (logicalX / LOGICAL_WIDTH) * rect.width + rect.left,
|
||||
clientY: (logicalY / LOGICAL_HEIGHT) * rect.height + rect.top,
|
||||
}),
|
||||
);
|
||||
|
||||
const canvas = getScreenCanvas(intersection.object.name);
|
||||
if (canvas) dispatchScreenEvent("mousedown", canvas, intersection);
|
||||
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 = () => {
|
||||
if (mousePressedButton) {
|
||||
physicalButtonsDown.delete(mousePressedButton);
|
||||
@@ -377,14 +400,19 @@ onMounted(() => {
|
||||
app.ready = true;
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
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);
|
||||
}
|
||||
topScreenTexture?.dispose();
|
||||
|
||||
Reference in New Issue
Block a user