feat(settings/options/startUp): intro and outro animation

This commit is contained in:
2026-02-06 23:18:16 +01:00
parent e95aec0b7d
commit 99ba13961e
8 changed files with 92 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { until } from "@vueuse/core"; import { until } from "@vueuse/core";
import gsap from "gsap";
const app = useAppStore(); const app = useAppStore();
const store = useSettingsStore(); const store = useSettingsStore();
@@ -9,6 +10,63 @@ const { assets } = useAssets();
const renderingModeAssets = const renderingModeAssets =
assets.images.settings.bottomScreen.options.renderingMode; 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 animation = reactive({
_3dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
_2dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
outroOffsetY: 0,
outroOpacity: 1,
});
const animateIntro = async () => {
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,
);
};
const animateOutro = async () => {
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({ const { selected, selectorPosition } = useButtonNavigation({
buttons: { buttons: {
_3dMode: [11, 27, 233, 74], _3dMode: [11, 27, 233, 74],
@@ -25,7 +83,8 @@ const { selected, selectorPosition } = useButtonNavigation({
}, },
}); });
const handleCancel = () => { const handleCancel = async () => {
await animateOutro();
store.closeSubMenu(); store.closeSubMenu();
}; };
@@ -39,7 +98,8 @@ const handleConfirm = () => {
mode === "3d" mode === "3d"
? $t("settings.options.startUp.confirmation3d") ? $t("settings.options.startUp.confirmation3d")
: $t("settings.options.startUp.confirmation2d"), : $t("settings.options.startUp.confirmation2d"),
onClosed: () => { onClosed: async () => {
await animateOutro();
store.closeSubMenu(); store.closeSubMenu();
}, },
timeout: 2000, timeout: 2000,
@@ -62,25 +122,35 @@ onRender((ctx) => {
logo: AtlasImage, logo: AtlasImage,
y: number, y: number,
active: boolean, active: boolean,
key: "_3dMode" | "_2dMode",
) => { ) => {
ctx.save(); ctx.save();
ctx.translate(16, y); ctx.translate(16, y + animation.outroOffsetY);
if (active) { const buttonWidth = renderingModeAssets.buttonBody.rect.width;
renderingModeAssets.buttonActive.draw(ctx, 0, 0, { colored: true });
} else {
renderingModeAssets.button.draw(ctx, 0, 0);
}
const buttonWidth = renderingModeAssets.button.rect.width; const bodyImg = active
? renderingModeAssets.buttonActiveBody
: renderingModeAssets.buttonBody;
const headerImg = active
? renderingModeAssets.buttonActiveHeader
: renderingModeAssets.buttonHeader;
const colorOpts = active ? { colored: true } : undefined;
ctx.fillStyle = "#000000"; ctx.globalAlpha = animation[key].opacity * animation.outroOpacity;
fillImageTextHCentered(ctx, logo, title, 0, 4, buttonWidth, 4);
bodyImg.draw(ctx, 0, HEADER_HEIGHT - 2, colorOpts);
ctx.fillStyle = "#282828"; ctx.fillStyle = "#282828";
const text = $t("settings.options.startUp.autoStart"); const text = $t("settings.options.startUp.autoStart");
fillTextHCenteredMultiline(ctx, text, 0, y, buttonWidth, 15); fillTextHCenteredMultiline(ctx, text, 0, y, 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(); ctx.restore();
}; };
@@ -89,12 +159,14 @@ onRender((ctx) => {
renderingModeAssets._3dMode, renderingModeAssets._3dMode,
32, 32,
selected.value === "_3dMode", selected.value === "_3dMode",
"_3dMode",
); );
drawButton( drawButton(
$t("settings.options.startUp.2dMode"), $t("settings.options.startUp.2dMode"),
renderingModeAssets._2dMode, renderingModeAssets._2dMode,
96, 96,
selected.value === "_2dMode", selected.value === "_2dMode",
"_2dMode",
); );
}); });
</script> </script>
@@ -108,5 +180,13 @@ onRender((ctx) => {
@activate-a="handleConfirm" @activate-a="handleConfirm"
/> />
<CommonButtonSelector :rect="selectorPosition" /> <CommonButtonSelector
:rect="[
selectorPosition[0],
selectorPosition[1] + animation.outroOffsetY,
selectorPosition[2],
selectorPosition[3],
]"
:opacity="animation[selected].opacity * animation.outroOpacity"
/>
</template> </template>

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 B