Files
pihkaal-me/app/stores/settings.ts

265 lines
6.2 KiB
TypeScript

import gsap from "gsap";
// not sure how i came up with it last night
export const SUBMENU_LABEL_CHANGE_DELAY = 0.25 + 0.15 - (0.167 + 0.08);
export const SETTINGS_MENUS = [
"options",
"clock",
"user",
"touchScreen",
] as const;
export const SETTINGS_SUB_MENUS = [
"optionsLanguage",
"options2048",
"optionsRenderingMode",
"clockAchievements",
"clockTime",
"clockDate",
"userBirthday",
"userUserName",
"userSnake",
"userColor",
"touchScreenTapTap",
] as const;
export type SettingsMenu = (typeof SETTINGS_MENUS)[number];
export type SettingsSubMenu = (typeof SETTINGS_SUB_MENUS)[number];
export type SettingsNavigableButton =
| SettingsMenu
| Exclude<SettingsSubMenu, "touchScreenTapTap">;
export const useSettingsStore = defineStore("settings", {
state: () => ({
currentMenu: null as SettingsMenu | null,
currentSubMenu: null as SettingsSubMenu | null,
menuExpanded: false,
selectedButton: "options" as SettingsNavigableButton,
notificationYOffset: 48,
barOffsetY: 24,
menuOffsets: [0, -48, -48, -48] as [number, number, number, number],
menuYOffset: 72,
submenuTransition: {
offsetY: 0,
selectorOffsetY: 0,
opacity: 1,
},
submenuBackground: {
offsetY: 16,
opacity: 0,
},
submenuButtonsOffsetY: 0,
animatingNotification: false,
isIntro: true,
isOutro: false,
}),
actions: {
openMenu(menu: SettingsMenu, expanded: boolean = false) {
this.currentMenu = menu;
this.menuExpanded = expanded;
this.currentSubMenu = null;
},
async openSubMenu(submenu: SettingsSubMenu) {
const { assets } = useAssets();
assets.audio.menuOpen.play();
await gsap
.timeline()
.to(this.submenuTransition, {
offsetY: -48,
selectorOffsetY: -140,
opacity: 0,
duration: 0.25,
ease: "none",
})
.fromTo(
this.submenuBackground,
{ offsetY: 16, opacity: 0 },
{ offsetY: 0, opacity: 1, duration: 0.25, ease: "none" },
"+=0.05",
)
.call(() => {
this.currentSubMenu = submenu;
});
const achievements = useAchievementsStore();
if (!achievements.advancement.visitedSettings.includes(submenu)) {
achievements.advancement.visitedSettings.push(submenu);
}
if (
achievements.advancement.visitedSettings.length ===
SETTINGS_SUB_MENUS.length
) {
achievements.unlock("settings_visit_all");
}
},
async closeSubMenu(silent = false) {
if (!silent) {
const { assets } = useAssets();
assets.audio.menuError.play();
}
await gsap
.timeline()
.to(this, {
submenuButtonsOffsetY: 24,
duration: 0.167,
ease: "none",
})
.call(() => {
this.currentSubMenu = null;
const confirmationModal = useConfirmationModal();
confirmationModal.buttonsYOffset = 0;
})
.fromTo(
this.submenuBackground,
{ offsetY: 0, opacity: 1 },
{ offsetY: 16, opacity: 0, duration: 0.25, ease: "none" },
0.167,
)
.to(
this,
{
submenuButtonsOffsetY: 0,
duration: 0.167,
ease: "none",
},
0.217,
)
.fromTo(
this.submenuTransition,
{
offsetY: -48,
selectorOffsetY: -140,
opacity: 0,
},
{
offsetY: 0,
selectorOffsetY: 0,
opacity: 1,
duration: 0.25,
ease: "none",
},
"+=0.05",
);
},
animateIntro() {
this.isIntro = true;
const { assets } = useAssets();
gsap
.timeline()
// bars
.fromTo(
this,
{ barOffsetY: 24 },
{ barOffsetY: 0, duration: 0.2, ease: "none" },
0,
)
// title notification
.fromTo(
this,
{ notificationYOffset: 48 },
{ notificationYOffset: 0, duration: 0.2, ease: "none" },
0.1,
)
// menus slide up
.fromTo(
this,
{ menuYOffset: 72 },
{ menuYOffset: 0, duration: 0.2, ease: "none" },
0,
)
// menus accordion
.fromTo(
this.menuOffsets,
{ 1: -48 },
{ 1: 0, duration: 0.143, ease: "none" },
0.2,
)
.call(() => assets.audio.settingsMenuIntro.play(), undefined, 0.2)
.fromTo(
this.menuOffsets,
{ 2: -48 },
{ 2: 0, duration: 0.143, ease: "none" },
0.343,
)
.fromTo(
this.menuOffsets,
{ 3: -48 },
{ 3: 0, duration: 0.143, ease: "none" },
0.486,
)
.call(() => {
this.isIntro = false;
});
},
animateOutro() {
this.isOutro = true;
const { assets } = useAssets();
gsap
.timeline()
.call(() => assets.audio.settingsMenuOutro.play())
// title notification
.fromTo(
this,
{ notificationYOffset: 0 },
{ notificationYOffset: 48, duration: 0.2, ease: "none" },
0,
)
// bars
.fromTo(
this,
{ barOffsetY: 0 },
{ barOffsetY: 24, duration: 0.2, ease: "none" },
0.1,
)
// menus accordion
.fromTo(
this.menuOffsets,
{ 3: 0 },
{ 3: -48, duration: 0.143, ease: "none" },
0,
)
.fromTo(
this.menuOffsets,
{ 2: 0 },
{ 2: -48, duration: 0.143, ease: "none" },
0.143,
)
.fromTo(
this.menuOffsets,
{ 1: 0 },
{ 1: -48, duration: 0.143, ease: "none" },
0.286,
)
// menus slide down
.fromTo(
this,
{ menuYOffset: 0 },
{ menuYOffset: 72, duration: 0.2, ease: "none" },
0.429,
)
.call(() => {
const app = useAppStore();
app.navigateTo("home");
this.isOutro = false;
});
},
},
});