fix: hide help buttons on screen too small to click on physical buttons

This commit is contained in:
2026-10-07 13:58:03 +02:00
parent 06b96fe5ba
commit f1ee6922b1
4 changed files with 44 additions and 31 deletions

View File

@@ -95,11 +95,9 @@ const handleTouchEnd = (event: TouchEvent) => {
);
};
const ndsScale = computed(() => {
const scaleX = (windowSize.width.value - 40) / 235;
const scaleY = (windowSize.height.value - 40) / 431;
return Math.min(scaleX, scaleY);
});
const ndsScale = computed(() =>
getNDS2DScale(windowSize.width.value, windowSize.height.value),
);
const gallery = useGalleryStore();
const TOP_SCREEN_OFFSET = 170;

View File

@@ -1,5 +1,4 @@
<script setup lang="ts">
import { useWindowSize } from "@vueuse/core";
import gsap from "gsap";
import { LazyLagModal } from "#components";
@@ -30,20 +29,6 @@ const bottomScreenCanvas = computed(() => bottomScreen.value?.canvas ?? null);
const isTouchDevice = () =>
"ontouchstart" in window || navigator.maxTouchPoints > 0;
const windowSize = useWindowSize();
watch(
[windowSize.width, windowSize.height],
([width, height]) => {
if (width / height > 614 / 667) {
if (app.booted) app.allowHints();
} else {
app.disallowHints();
}
},
{ immediate: true },
);
const helpButton = useTemplateRef("helpButton");
let helpAnimation: gsap.core.Timeline | null = null;
@@ -105,11 +90,16 @@ const hideHelpLabels = () => {
});
};
// help button is removed when hints are disallowed, no need to animate it out
watch(
() => app.hintsAllowed,
(allowed) => {
if (!allowed) hideHelpLabels();
if (allowed) return;
helpAnimation?.kill();
helpAnimation = null;
app.hintsVisible = false;
},
{ immediate: true },
);
onMounted(async () => {
@@ -129,9 +119,7 @@ onMounted(async () => {
});
}
const scaleX = (window.innerWidth - 40) / 235;
const scaleY = (window.innerHeight - 40) / 431;
const scale = Math.min(scaleX, scaleY);
const scale = getNDS2DScale(window.innerWidth, window.innerHeight);
if (app.settings.renderingMode === "2d" && scale < 1) return;

View File

@@ -1,4 +1,5 @@
import { z } from "zod/mini";
import { useWindowSize } from "@vueuse/core";
import type * as THREE from "three";
export const LOGICAL_WIDTH = 256;
@@ -18,6 +19,24 @@ export const APP_COLORS = [
const STORAGE_ID = "nds-settings";
// 2d nds is 414x431, scaled so the screens fit, it overflows horizontally on narrow viewports
export const getNDS2DScale = (width: number, height: number) =>
Math.min((width - 40) / 235, (height - 40) / 431);
// 3d: fixed vertical fov, so buttons clip at a fixed aspect ratio (measured: 810px wide at 865px tall)
const HINTS_MIN_ASPECT_RATIO_3D = 810 / 865;
// 2d: horizontal span of the physical buttons (A button is ~14px from the edge)
const NDS2D_BUTTONS_SPAN = 386;
const screenFitsHints = (
width: number,
height: number,
renderingMode: "3d" | "2d",
) =>
renderingMode === "3d"
? width / height > HINTS_MIN_ASPECT_RATIO_3D
: NDS2D_BUTTONS_SPAN * getNDS2DScale(width, height) <= width;
const settingsSchema = z.object({
color: z.object({
col: z.number(),
@@ -55,7 +74,9 @@ export const useAppStore = defineStore("app", {
visitedGallery: false,
camera: null as THREE.Camera | null,
hintsVisible: false,
hintsAllowed: false,
// hints wanted by the current app state (intro done, not in gallery)
hintsRequested: false,
windowSize: useWindowSize(),
lagDetected: false,
lagModalOpen: false,
};
@@ -96,12 +117,11 @@ export const useAppStore = defineStore("app", {
},
allowHints() {
this.hintsAllowed = true;
this.hintsRequested = true;
},
disallowHints() {
this.hintsAllowed = false;
this.hintsVisible = false;
this.hintsRequested = false;
},
showHints() {
@@ -128,5 +148,14 @@ export const useAppStore = defineStore("app", {
row: state.settings.color.row,
hex: APP_COLORS[state.settings.color.row]![state.settings.color.col]!,
}),
// hints wanted and screen large enough
hintsAllowed: (state) =>
state.hintsRequested &&
screenFitsHints(
state.windowSize.width,
state.windowSize.height,
state.settings.renderingMode,
),
},
});

View File

@@ -67,9 +67,7 @@ export const useIntroStore = defineStore("intro", {
)
.call(() => {
const app = useAppStore();
if (window.innerWidth / window.innerHeight > 614 / 667) {
app.allowHints();
}
});
},