Files
pihkaal-me/app/stores/intro.ts
Pihkaal cd64082e84
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m47s
feat(2d-nds): intro animation
2026-02-27 12:17:53 +01:00

104 lines
2.3 KiB
TypeScript

import gsap from "gsap";
export const useIntroStore = defineStore("intro", {
state: () => ({
intro: {
textOpacity: 0,
logoFrameIndex: 0,
},
outro: {
textOpacity: 1,
backgroundOpacity: 0,
},
isIntro: true,
isOutro: false,
isAnimating: false,
}),
actions: {
animateIntro() {
if (this.isAnimating) return;
this.isAnimating = true;
this.isIntro = true;
const { assets } = useAssets();
const delay = 3;
const totalFrames = Object.keys(assets.images.intro.logoAnimated).length;
const logoDuration = totalFrames / 25;
gsap
.timeline({
onComplete: () => {
this.isIntro = false;
this.isAnimating = false;
},
})
.call(
() => {
const now = new Date();
const isBirthday = now.getMonth() === 3 && now.getDate() === 25;
(isBirthday
? assets.audio.birthdayStartup
: assets.audio.startUp
).play();
},
undefined,
delay,
)
.to(
this.intro,
{
textOpacity: 1,
duration: 0.1,
ease: "none",
},
delay,
)
.to(
this.intro,
{
logoFrameIndex: totalFrames - 1,
duration: logoDuration,
ease: "steps(" + (totalFrames - 1) + ")",
},
delay,
)
.call(() => {
const app = useAppStore();
if (window.innerWidth / window.innerHeight > 614 / 667) {
app.allowHints();
}
});
},
animateOutro() {
this.isOutro = true;
const { assets } = useAssets();
assets.audio.tinyClick.play(0.8);
gsap
.timeline()
.to(this.outro, {
textOpacity: 0,
duration: 0.25,
ease: "none",
})
.to(this.outro, {
backgroundOpacity: 1,
duration: 0.5,
delay: 0.2,
ease: "none",
})
.call(() => {
const app = useAppStore();
const achievements = useAchievementsStore();
app.booted = true;
achievements.unlock("boot");
});
},
},
});