feat(home): use new navigation system

This commit is contained in:
2025-11-14 23:53:42 +01:00
parent 1d14ad1450
commit b64139350c

View File

@@ -5,151 +5,85 @@ import PictochatButton from "./PictochatButton.vue";
import DownloadPlayButton from "./DownloadPlayButton.vue"; import DownloadPlayButton from "./DownloadPlayButton.vue";
import Selector from "./Selector.vue"; import Selector from "./Selector.vue";
type ButtonConfig = {
x: number;
y: number;
sx: number;
sy: number;
sw: number;
sh: number;
};
const BUTTONS_CONFIG = { const BUTTONS_CONFIG = {
game: { x: 33, y: 25, sx: 31, sy: 23, sw: 193, sh: 49 }, game: [31, 23, 193, 49],
pictochat: { x: 32, y: 72, sx: 31, sy: 71, sw: 97, sh: 49 }, pictochat: [31, 71, 97, 49],
downloadPlay: { x: 128, y: 72, sx: 127, sy: 71, sw: 97, sh: 49 }, downloadPlay: [127, 71, 97, 49],
} as const satisfies Record<string, ButtonConfig>; } as const satisfies Record<string, ButtonConfig>;
type ButtonType = keyof typeof BUTTONS_CONFIG; type ButtonType = keyof typeof BUTTONS_CONFIG;
const selectedButton = ref<ButtonType>("game");
const nextBottomButton = ref<"downloadPlay" | "pictochat">("pictochat");
const selectorPosition = computed(() => BUTTONS_CONFIG[selectedButton.value]);
const animationPercentage = ref(0); const animationPercentage = ref(0);
const { selectedButton, selectorPosition } = useButtonNavigation({
buttons: BUTTONS_CONFIG,
initialButton: "game",
onButtonClick: (buttonName) => {
gsap.fromTo(
animationPercentage,
{ value: 0 },
{
value: 1,
duration: 0.35,
ease: "none",
onComplete: () => {
if (buttonName === "pictochat") {
navigateTo("/contact");
} else {
throw new Error(`Not implemented: ${buttonName}`);
}
},
},
);
},
navigation: {
game: {
down: "last",
left: "pictochat",
right: "downloadPlay",
horizontalMode: "preview",
},
pictochat: {
up: "game",
right: "downloadPlay",
},
downloadPlay: {
up: "game",
left: "pictochat",
},
},
});
const getButtonOffset = (button: ButtonType) => { const getButtonOffset = (button: ButtonType) => {
if (selectedButton.value === button) return animationPercentage.value * -200; if (selectedButton.value === button) return animationPercentage.value * -200;
return 0; return 0;
}; };
const getOpacity = () => (1 - animationPercentage.value) * 100; const getOpacity = () => (1 - animationPercentage.value) * 100;
useScreenClick((x: number, y: number) => {
if (animationPercentage.value != 0) return;
for (const [buttonName, config] of Object.entries(BUTTONS_CONFIG) as [
ButtonType,
ButtonConfig,
][]) {
if (
x >= config.sx &&
x <= config.sx + config.sw &&
y >= config.sy &&
y <= config.sy + config.sh
) {
if (selectedButton.value === buttonName) {
gsap.fromTo(
animationPercentage,
{ value: 0 },
{
value: 1,
duration: 0.35,
ease: "none",
onComplete: () => {
throw new Error("not implemented: onComplete in button click");
},
},
);
} else {
selectedButton.value = buttonName;
}
if (buttonName === "pictochat" || buttonName === "downloadPlay") {
nextBottomButton.value = buttonName;
}
break;
}
}
});
const handleKeyPress = (event: KeyboardEvent) => {
switch (event.key) {
case "ArrowUp":
event.preventDefault();
if (
selectedButton.value === "downloadPlay" ||
selectedButton.value === "pictochat"
) {
selectedButton.value = "game";
}
break;
case "ArrowDown":
event.preventDefault();
if (selectedButton.value === "game") {
selectedButton.value = nextBottomButton.value;
}
break;
case "ArrowRight":
event.preventDefault();
if (selectedButton.value === "game") {
nextBottomButton.value = "downloadPlay";
} else if (selectedButton.value === "pictochat") {
nextBottomButton.value = "downloadPlay";
selectedButton.value = "downloadPlay";
}
break;
case "ArrowLeft":
event.preventDefault();
if (selectedButton.value === "game") {
nextBottomButton.value = "pictochat";
} else if (selectedButton.value === "downloadPlay") {
nextBottomButton.value = "pictochat";
selectedButton.value = "pictochat";
}
break;
case "Enter":
case " ":
throw "Not implemented";
}
};
onMounted(() => {
window.addEventListener("keydown", handleKeyPress);
});
onUnmounted(() => {
window.removeEventListener("keydown", handleKeyPress);
});
</script> </script>
<template> <template>
<GameButton <GameButton
:x="BUTTONS_CONFIG.game.x" :x="33"
:y="BUTTONS_CONFIG.game.y + getButtonOffset('game')" :y="25 + getButtonOffset('game')"
:opacity="getOpacity()" :opacity="getOpacity()"
/> />
<DownloadPlayButton <DownloadPlayButton
:x="BUTTONS_CONFIG.downloadPlay.x" :x="128"
:y="BUTTONS_CONFIG.downloadPlay.y + getButtonOffset('downloadPlay')" :y="72 + getButtonOffset('downloadPlay')"
:opacity="getOpacity()" :opacity="getOpacity()"
/> />
<PictochatButton <PictochatButton
:x="BUTTONS_CONFIG.pictochat.x" :x="32"
:y="BUTTONS_CONFIG.pictochat.y + getButtonOffset('pictochat')" :y="72 + getButtonOffset('pictochat')"
:opacity="getOpacity()" :opacity="getOpacity()"
/> />
<Selector <Selector
:x="selectorPosition.sx" :x="selectorPosition[0]"
:y="selectorPosition.sy" :y="selectorPosition[1]"
:width="selectorPosition.sw" :width="selectorPosition[2]"
:height="selectorPosition.sh" :height="selectorPosition[3]"
:opacity="getOpacity()" :opacity="getOpacity()"
/> />
</template> </template>