Files

213 lines
5.0 KiB
Vue

<script setup lang="ts">
import { until } from "@vueuse/core";
import gsap from "gsap";
const app = useAppStore();
const store = useSettingsStore();
const confirmationModal = useConfirmationModal();
const { onRender } = useScreen();
const { assets } = useAssets();
const renderingModeAssets =
assets.images.settings.bottomScreen.options.renderingMode;
const HEADER_HEIGHT = renderingModeAssets.buttonHeader.rect.height;
const HEADER_SLIDE_DURATION = 0.2;
const BUTTON_STAGGER = 0.3;
const SLIDE_OFFSET = 96;
const SLIDE_DURATION = 0.25;
const isAnimating = ref(true);
const bLabel = ref($t("common.goBack"));
const aLabel = ref($t("common.select"));
const animation = reactive({
_3dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
_2dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
outroOffsetY: 0,
outroOpacity: 1,
});
const animateIntro = async () => {
isAnimating.value = true;
await gsap
.timeline()
.to(
animation._3dMode,
{
opacity: 1,
headerOffsetY: 0,
duration: HEADER_SLIDE_DURATION,
ease: "none",
},
0,
)
.to(
animation._2dMode,
{
opacity: 1,
headerOffsetY: 0,
duration: HEADER_SLIDE_DURATION,
ease: "none",
},
BUTTON_STAGGER,
)
.call(
() => {
bLabel.value = $t("common.cancel");
aLabel.value = $t("common.confirm");
},
[],
SUBMENU_LABEL_CHANGE_DELAY,
);
isAnimating.value = false;
};
const animateOutro = async () => {
isAnimating.value = true;
await gsap
.timeline()
.to(
animation,
{ outroOffsetY: SLIDE_OFFSET, duration: SLIDE_DURATION, ease: "none" },
0,
)
.to(
animation,
{ outroOpacity: 0, duration: SLIDE_DURATION, ease: "none" },
0,
);
};
onMounted(() => {
animateIntro();
});
const { selected, selectorPosition } = useButtonNavigation({
buttons: {
_3dMode: [11, 27, 233, 74],
_2dMode: [11, 91, 233, 74],
},
initialButton: app.settings.renderingMode === "3d" ? "_3dMode" : "_2dMode",
onActivate: () => handleActivateA(),
navigation: {
_3dMode: { down: "_2dMode" },
_2dMode: { up: "_3dMode" },
},
disabled: isAnimating,
selectorAnimation: {
ease: "none",
duration: 0.065,
},
});
const handleActivateB = async () => {
if (isAnimating.value) return;
await animateOutro();
store.closeSubMenu();
};
const handleActivateA = () => {
if (isAnimating.value) return;
const mode = selected.value === "_3dMode" ? "3d" : "2d";
app.setRenderingMode(mode);
const showConfirmation = () => {
confirmationModal.open({
text:
mode === "3d"
? $t("settings.options.renderingMode.confirmation3d")
: $t("settings.options.renderingMode.confirmation2d"),
onClosed: async () => {
await animateOutro();
store.closeSubMenu(true);
},
keepButtonsDown: true,
timeout: 2000,
});
};
until(() => app.ready)
.toBeTruthy()
.then(showConfirmation);
};
onRender((ctx) => {
ctx.font = "10px NDS10";
const drawButton = (
title: string,
logo: AtlasImage,
y: number,
active: boolean,
key: "_3dMode" | "_2dMode",
) => {
ctx.save();
ctx.translate(16, y + animation.outroOffsetY);
const buttonWidth = renderingModeAssets.buttonBody.rect.width;
const bodyImg = active
? renderingModeAssets.buttonActiveBody
: renderingModeAssets.buttonBody;
const headerImg = active
? renderingModeAssets.buttonActiveHeader
: renderingModeAssets.buttonHeader;
const colorOpts = active ? { colored: true } : undefined;
ctx.globalAlpha = animation[key].opacity * animation.outroOpacity;
bodyImg.draw(ctx, 0, HEADER_HEIGHT - 2, colorOpts);
ctx.fillStyle = "#282828";
const descKey = key === "_3dMode" ? "3dDescription" : "2dDescription";
const text = $t(`settings.options.renderingMode.${descKey}`);
fillTextHCenteredMultiline(ctx, text, 0, 20 + 9, buttonWidth, 15);
ctx.translate(0, animation[key].headerOffsetY);
headerImg.draw(ctx, 0, 0, colorOpts);
ctx.fillStyle = "#000000";
fillImageTextHCentered(ctx, logo, title, 0, 4, buttonWidth, 4);
ctx.globalAlpha = 1;
ctx.restore();
};
drawButton(
$t("settings.options.renderingMode.3dMode"),
renderingModeAssets._3dMode,
32,
selected.value === "_3dMode",
"_3dMode",
);
drawButton(
$t("settings.options.renderingMode.2dMode"),
renderingModeAssets._2dMode,
96,
selected.value === "_2dMode",
"_2dMode",
);
});
</script>
<template>
<CommonButtons
:y-offset="confirmationModal.buttonsYOffset + store.submenuButtonsOffsetY"
:b-label="bLabel"
:a-label="aLabel"
no-keyboard-a
@activate-a="handleActivateA"
@activate-b="handleActivateB"
/>
<CommonButtonSelector
:rect="[
selectorPosition[0],
selectorPosition[1] + animation.outroOffsetY,
selectorPosition[2],
selectorPosition[3],
]"
:opacity="animation[selected].opacity * animation.outroOpacity"
/>
</template>