feat(gallery): transition to and from the nds

This commit is contained in:
2026-01-04 20:53:52 +01:00
parent 1f61eee93a
commit 18f91981ec
13 changed files with 253 additions and 14 deletions

View File

@@ -1,4 +1,5 @@
import { z } from "zod/mini";
import type * as THREE from "three";
const STORAGE_ID = "app_settings";
@@ -29,6 +30,7 @@ export const useAppStore = defineStore("app", {
booted: false,
settings,
screen: "home" as AppScreen,
camera: null as THREE.Camera | null,
};
},
@@ -41,6 +43,10 @@ export const useAppStore = defineStore("app", {
this.screen = screen;
},
setCamera(camera: THREE.Camera) {
this.camera = camera;
},
save() {
localStorage.setItem(STORAGE_ID, JSON.stringify(this.settings));
},

147
app/stores/gallery.ts Normal file
View File

@@ -0,0 +1,147 @@
import gsap from "gsap";
import * as THREE from "three";
export const useGalleryStore = defineStore("gallery", {
state: () => ({
intro: {
fadeOpacity: 0,
},
outro: {
fadeOpacity: 1,
},
isIntro: true,
isOutro: false,
shouldAnimateOutro: false,
}),
actions: {
animateIntro() {
const CAMERA_DELAY = 0.7;
const CAMERA_DURATION = 3;
const FADE_DELAY = 0;
const FADE_DURATION = 1;
this.isIntro = true;
this.isOutro = false;
const app = useAppStore();
if (app.camera) {
gsap.fromTo(
app.camera.position,
{
x: 0,
y: 10,
z: 12,
},
{
x: 0,
y: 3,
z: -1.7,
duration: CAMERA_DURATION,
delay: CAMERA_DELAY,
ease: "power2.inOut",
},
);
gsap.fromTo(
app.camera.rotation,
{
x: THREE.MathUtils.degToRad(-38.3),
y: 0,
z: 0,
},
{
x: THREE.MathUtils.degToRad(-25),
y: 0,
z: 0,
duration: CAMERA_DURATION * 0.9,
delay: CAMERA_DELAY,
ease: "power2.inOut",
},
);
}
gsap.fromTo(
this.intro,
{ fadeOpacity: 0 },
{
fadeOpacity: 1,
duration: FADE_DURATION,
delay: FADE_DELAY,
ease: "none",
},
);
setTimeout(() => {
navigateTo("/gallery");
}, 3150);
},
animateOutro() {
const CAMERA_DELAY = 0;
const CAMERA_DURATION = 3;
const FADE_DELAY = 2.3;
const FADE_DURATION = 1;
this.isIntro = false;
this.isOutro = true;
const app = useAppStore();
if (app.camera) {
gsap.fromTo(
app.camera.position,
{
x: 0,
y: 3,
z: -1.7,
},
{
x: 0,
y: 10,
z: 12,
duration: CAMERA_DURATION,
delay: CAMERA_DELAY,
ease: "power2.inOut",
},
);
gsap.fromTo(
app.camera.rotation,
{
x: THREE.MathUtils.degToRad(-25),
y: 0,
z: 0,
},
{
x: THREE.MathUtils.degToRad(-38.3),
y: 0,
z: 0,
duration: CAMERA_DURATION * 0.9,
delay: CAMERA_DELAY,
ease: "power2.inOut",
},
);
}
gsap.fromTo(
this.outro,
{ fadeOpacity: 1 },
{
fadeOpacity: 0,
duration: FADE_DURATION,
delay: FADE_DELAY,
ease: "none",
},
);
setTimeout(() => {
this.isOutro = false;
app.navigateTo("home");
}, 3310);
},
},
});

View File

@@ -61,8 +61,13 @@ export const useHomeStore = defineStore("home", {
const timeline = gsap.timeline({
onComplete: () => {
this.isOutro = true;
const app = useAppStore();
app.navigateTo(to);
if (to === "gallery") {
app.navigateTo("gallery");
} else {
app.navigateTo(to);
}
},
});