fix(nds): wrong touch detection

This commit is contained in:
2026-02-13 16:21:54 +01:00
parent cf3b4bd175
commit 555ecf8d80
2 changed files with 60 additions and 40 deletions

View File

@@ -326,26 +326,6 @@ const dispatchScreenEvent = (
);
};
const dispatchScreenTouchEvent = (
type: string,
canvas: HTMLCanvasElement,
intersection: THREE.Intersection,
) => {
const coords = toScreenCoords(canvas, intersection);
if (!coords) return;
const touch = new Touch({ identifier: 0, target: canvas, ...coords });
canvas.dispatchEvent(
new TouchEvent(type, {
bubbles: true,
cancelable: true,
touches: type === "touchend" ? [] : [touch],
changedTouches: [touch],
}),
);
};
const BUTTON_MAP = {
[X_BUTTON]: "X",
[A_BUTTON]: "A",
@@ -441,10 +421,40 @@ const handleMouseUp = (event: MouseEvent) => {
if (canvas) dispatchScreenEvent("mouseup", canvas, intersection);
};
const SWIPE_THRESHOLD = 30;
let swipeStartX = 0;
let swipeStartY = 0;
const dispatchSwipe = (endX: number, endY: number) => {
const deltaX = endX - swipeStartX;
const deltaY = endY - swipeStartY;
const absDeltaX = Math.abs(deltaX);
const absDeltaY = Math.abs(deltaY);
if (Math.max(absDeltaX, absDeltaY) < SWIPE_THRESHOLD) return;
const direction =
absDeltaX > absDeltaY
? deltaX > 0
? "RIGHT"
: "LEFT"
: deltaY > 0
? "DOWN"
: "UP";
window.dispatchEvent(
new KeyboardEvent("keydown", { key: `NDS_SWIPE_${direction}` }),
);
};
const handleTouchStart = (event: TouchEvent) => {
const touch = event.touches[0];
if (!touch) return;
event.preventDefault();
swipeStartX = touch.clientX;
swipeStartY = touch.clientY;
if (!hasAnimated.value) {
animateIntro();
return;
@@ -452,7 +462,6 @@ const handleTouchStart = (event: TouchEvent) => {
handleInteraction(touch.clientX, touch.clientY, (canvas, intersection) => {
dispatchScreenEvent("mousedown", canvas, intersection);
dispatchScreenTouchEvent("touchstart", canvas, intersection);
});
};
@@ -462,14 +471,22 @@ const handleTouchEnd = (event: TouchEvent) => {
const touch = event.changedTouches[0];
if (!touch) return;
dispatchSwipe(touch.clientX, touch.clientY);
const intersection = raycast(touch.clientX, touch.clientY);
if (!intersection?.uv) return;
const canvas = getScreenCanvas(intersection.object.name);
if (canvas) {
dispatchScreenEvent("click", canvas, intersection);
dispatchScreenTouchEvent("touchend", canvas, intersection);
}
document.dispatchEvent(
new MouseEvent("mouseup", {
clientX: touch.clientX,
clientY: touch.clientY,
}),
);
};
onMounted(() => {