feat(3d-nds): lag detection

This commit is contained in:
2026-02-24 16:17:43 +01:00
parent 187cc8d574
commit 2d4210b031
6 changed files with 78 additions and 2 deletions

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
const emit = defineEmits<{ close: [] }>();
const app = useAppStore();
const keep3d = () => {
app.lagDetected = false;
emit("close");
};
const switch2d = () => {
app.setRenderingMode("2d");
emit("close");
};
</script>
<template>
<UModal :open="true" :dismissible="false" :title="$t('lagModal.title')" :ui="{ footer: 'justify-end' }">
<template #body>
{{ $t('lagModal.body') }}
</template>
<template #footer>
<UButton variant="ghost" color="neutral" :label="$t('lagModal.keep3d')" @click="keep3d" />
<UButton color="neutral" :label="$t('lagModal.switch2d')" @click="switch2d" />
</template>
</UModal>
</template>

View File

@@ -195,7 +195,12 @@ watch(
{ immediate: true }, { immediate: true },
); );
const { onRender } = useLoop(); const { onRender, onBeforeRender } = useLoop();
const LAG_FPS_THRESHOLD = 440;
const LAG_DURATION_SECS = 1;
let lagSeconds = 0;
let lagCheckDone = false;
const HINT_SPRITE_SCALE = 2; const HINT_SPRITE_SCALE = 2;
const HINT_SPRITE_DPR = 4; const HINT_SPRITE_DPR = 4;
@@ -337,10 +342,30 @@ useKeyUp(({ ndsButton }) => {
} }
}); });
onRender(({ delta }) => { // lag detection
onBeforeRender(({ delta }) => {
if (!lagCheckDone) {
const fps = 1 / delta;
if (fps < LAG_FPS_THRESHOLD) {
lagSeconds += delta;
if (lagSeconds >= LAG_DURATION_SECS) {
lagCheckDone = true;
app.lagDetected = true;
}
} else {
lagSeconds = 0;
}
}
});
// upate screens
onRender(() => {
if (topScreenTexture) topScreenTexture.needsUpdate = true; if (topScreenTexture) topScreenTexture.needsUpdate = true;
if (bottomScreenTexture) bottomScreenTexture.needsUpdate = true; if (bottomScreenTexture) bottomScreenTexture.needsUpdate = true;
});
// update physical buttons
onBeforeRender(({ delta }) => {
// cross // cross
const crossButton = meshes.get(CROSS_BUTTON); const crossButton = meshes.get(CROSS_BUTTON);
if (crossButton) { if (crossButton) {

View File

@@ -7,7 +7,11 @@ export type KeyDownCallback = (params: {
}) => void; }) => void;
export const useKeyDown = (callback: KeyDownCallback) => { export const useKeyDown = (callback: KeyDownCallback) => {
const app = useAppStore();
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (app.lagDetected) return;
const ndsButton = mapCodeToNDS(event.code); const ndsButton = mapCodeToNDS(event.code);
callback({ callback({
key: ndsButton ? `NDS_${ndsButton}` : event.key, key: ndsButton ? `NDS_${ndsButton}` : event.key,

View File

@@ -1,11 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import { useWindowSize } from "@vueuse/core"; import { useWindowSize } from "@vueuse/core";
import gsap from "gsap"; import gsap from "gsap";
import { LazyLagModal } from "#components";
const { isReady } = useAssets(); const { isReady } = useAssets();
const app = useAppStore(); const app = useAppStore();
const overlay = useOverlay();
const lagModal = overlay.create(LazyLagModal);
watch(
() => app.lagDetected,
(detected) => {
if (detected) lagModal.open();
},
);
const topScreen = useTemplateRef("topScreen"); const topScreen = useTemplateRef("topScreen");
const bottomScreen = useTemplateRef("bottomScreen"); const bottomScreen = useTemplateRef("bottomScreen");

View File

@@ -54,6 +54,7 @@ export const useAppStore = defineStore("app", {
camera: null as THREE.Camera | null, camera: null as THREE.Camera | null,
hintsVisible: false, hintsVisible: false,
hintsAllowed: false, hintsAllowed: false,
lagDetected: false,
}; };
}, },
@@ -65,6 +66,7 @@ export const useAppStore = defineStore("app", {
setRenderingMode(mode: Settings["renderingMode"]) { setRenderingMode(mode: Settings["renderingMode"]) {
this.ready = mode === "2d"; this.ready = mode === "2d";
this.settings.renderingMode = mode; this.settings.renderingMode = mode;
if (mode === "3d") this.lagDetected = false;
this.save(); this.save();
}, },

View File

@@ -1,4 +1,10 @@
{ {
"lagModal": {
"title": "Performance issues detected",
"body": "Your device seems to be struggling with 3D rendering. Switch to 2D mode for a smoother experience.",
"keep3d": "Keep 3D",
"switch2d": "Switch to 2D"
},
"common": { "common": {
"cancel": "Cancel", "cancel": "Cancel",
"confirm": "Confirm", "confirm": "Confirm",