feat(settings): intro and outro animation

This commit is contained in:
2026-02-05 20:44:19 +01:00
parent 098285ee82
commit 1236e86981
10 changed files with 306 additions and 52 deletions

View File

@@ -13,6 +13,7 @@ export const useHomeStore = defineStore("home", {
intro: {
statusBarY: -20,
stage1Opacity: 0,
topScreenOpacity: 0,
},
outro: {
@@ -44,33 +45,51 @@ export const useHomeStore = defineStore("home", {
animateIntro() {
this.isIntro = true;
const app = useAppStore();
const timeline = gsap.timeline({
onComplete: () => {
this.isIntro = false;
},
});
timeline
.fromTo(
this.intro,
{ stage1Opacity: 0 },
{
stage1Opacity: 1,
duration: 0.5,
ease: "none",
},
0,
)
.fromTo(
this.intro,
{ statusBarY: -20 },
{
statusBarY: 0,
duration: 0.15,
ease: "none",
},
0.35,
);
timeline.fromTo(
this.intro,
{ stage1Opacity: 0 },
{
stage1Opacity: 1,
duration: 0.5,
ease: "none",
},
0,
);
if (app.previousScreen !== "settings") {
timeline
.fromTo(
this.intro,
{ topScreenOpacity: 0 },
{
topScreenOpacity: 1,
duration: 0.5,
ease: "none",
},
0,
)
.fromTo(
this.intro,
{ statusBarY: -20 },
{
statusBarY: 0,
duration: 0.15,
ease: "none",
},
0.35,
);
} else {
this.intro.topScreenOpacity = 1;
this.intro.statusBarY = 0;
}
},
animateOutro(to: AppScreen) {

View File

@@ -1,3 +1,5 @@
import gsap from "gsap";
export const SETTINGS_MENUS = [
"options",
"clock",
@@ -31,6 +33,13 @@ export const useSettingsStore = defineStore("settings", {
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,
isIntro: true,
isOutro: false,
}),
actions: {
@@ -58,5 +67,107 @@ export const useSettingsStore = defineStore("settings", {
closeSubMenu() {
this.currentSubMenu = null;
},
animateIntro() {
this.isIntro = true;
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.1, ease: "none" },
0.2,
)
.fromTo(
this.menuOffsets,
{ 2: -48 },
{ 2: 0, duration: 0.1, ease: "none" },
0.3,
)
.fromTo(
this.menuOffsets,
{ 3: -48 },
{ 3: 0, duration: 0.1, ease: "none" },
0.4,
)
.call(() => {
this.isIntro = false;
});
},
animateOutro() {
this.isOutro = true;
gsap
.timeline()
// 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.1, ease: "none" },
0,
)
.fromTo(
this.menuOffsets,
{ 2: 0 },
{ 2: -48, duration: 0.1, ease: "none" },
0.1,
)
.fromTo(
this.menuOffsets,
{ 1: 0 },
{ 1: -48, duration: 0.1, ease: "none" },
0.2,
)
// menus slide down
.fromTo(
this,
{ menuYOffset: 0 },
{ menuYOffset: 72, duration: 0.2, ease: "none" },
0.3,
)
.call(() => {
const app = useAppStore();
app.navigateTo("home");
this.isOutro = false;
});
},
},
});