feat(nds): intro animation
This commit is contained in:
@@ -1,6 +1,19 @@
|
||||
import gsap from "gsap";
|
||||
import * as THREE from "three";
|
||||
|
||||
const ANIMATION = {
|
||||
NDS_CAMERA_POSITION: new THREE.Vector3(0, 14, 10),
|
||||
NDS_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-55), 0, 0),
|
||||
GALLERY_CAMERA_POSITION: new THREE.Vector3(0, 4.5, -3),
|
||||
GALLERY_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-62), 0, 0),
|
||||
|
||||
CAMERA_DURATION: 3,
|
||||
CAMERA_ROTATION_OVERLAP: 0.1,
|
||||
FADE_DURATION: 1,
|
||||
FADE_CAMERA_OVERLAP: 0.9,
|
||||
NAVIGATE_DELAY: 3150,
|
||||
};
|
||||
|
||||
export const useGalleryStore = defineStore("gallery", {
|
||||
state: () => ({
|
||||
intro: {
|
||||
@@ -18,93 +31,40 @@ export const useGalleryStore = defineStore("gallery", {
|
||||
|
||||
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",
|
||||
},
|
||||
);
|
||||
}
|
||||
// Intro: Fade starts first (at 0), camera starts after with overlap
|
||||
const cameraDelay =
|
||||
ANIMATION.FADE_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
||||
|
||||
gsap.fromTo(
|
||||
this.intro,
|
||||
{ fadeOpacity: 0 },
|
||||
{
|
||||
fadeOpacity: 1,
|
||||
duration: FADE_DURATION,
|
||||
delay: FADE_DELAY,
|
||||
duration: ANIMATION.FADE_DURATION,
|
||||
delay: 0,
|
||||
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: ANIMATION.NDS_CAMERA_POSITION.x,
|
||||
y: ANIMATION.NDS_CAMERA_POSITION.y,
|
||||
z: ANIMATION.NDS_CAMERA_POSITION.z,
|
||||
},
|
||||
{
|
||||
x: 0,
|
||||
y: 10,
|
||||
z: 12,
|
||||
duration: CAMERA_DURATION,
|
||||
delay: CAMERA_DELAY,
|
||||
x: ANIMATION.GALLERY_CAMERA_POSITION.x,
|
||||
y: ANIMATION.GALLERY_CAMERA_POSITION.y,
|
||||
z: ANIMATION.GALLERY_CAMERA_POSITION.z,
|
||||
duration: ANIMATION.CAMERA_DURATION,
|
||||
delay: cameraDelay,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
);
|
||||
@@ -112,16 +72,71 @@ export const useGalleryStore = defineStore("gallery", {
|
||||
gsap.fromTo(
|
||||
app.camera.rotation,
|
||||
{
|
||||
x: THREE.MathUtils.degToRad(-25),
|
||||
y: 0,
|
||||
z: 0,
|
||||
x: ANIMATION.NDS_CAMERA_ROTATION.x,
|
||||
y: ANIMATION.NDS_CAMERA_ROTATION.y,
|
||||
z: ANIMATION.NDS_CAMERA_ROTATION.z,
|
||||
},
|
||||
{
|
||||
x: THREE.MathUtils.degToRad(-38.3),
|
||||
y: 0,
|
||||
z: 0,
|
||||
duration: CAMERA_DURATION * 0.9,
|
||||
delay: CAMERA_DELAY,
|
||||
x: ANIMATION.GALLERY_CAMERA_ROTATION.x,
|
||||
y: ANIMATION.GALLERY_CAMERA_ROTATION.y,
|
||||
z: ANIMATION.GALLERY_CAMERA_ROTATION.z,
|
||||
duration:
|
||||
ANIMATION.CAMERA_DURATION *
|
||||
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
||||
delay: cameraDelay,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
navigateTo("/gallery");
|
||||
}, ANIMATION.NAVIGATE_DELAY);
|
||||
},
|
||||
|
||||
animateOutro() {
|
||||
this.isIntro = false;
|
||||
this.isOutro = true;
|
||||
|
||||
const app = useAppStore();
|
||||
|
||||
// Outro: Camera starts first (at 0), fade starts after with overlap
|
||||
const fadeDelay =
|
||||
ANIMATION.CAMERA_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
||||
|
||||
if (app.camera) {
|
||||
gsap.fromTo(
|
||||
app.camera.position,
|
||||
{
|
||||
x: ANIMATION.GALLERY_CAMERA_POSITION.x,
|
||||
y: ANIMATION.GALLERY_CAMERA_POSITION.y,
|
||||
z: ANIMATION.GALLERY_CAMERA_POSITION.z,
|
||||
},
|
||||
{
|
||||
x: ANIMATION.NDS_CAMERA_POSITION.x,
|
||||
y: ANIMATION.NDS_CAMERA_POSITION.y,
|
||||
z: ANIMATION.NDS_CAMERA_POSITION.z,
|
||||
duration: ANIMATION.CAMERA_DURATION,
|
||||
delay: 0,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
);
|
||||
|
||||
gsap.fromTo(
|
||||
app.camera.rotation,
|
||||
{
|
||||
x: ANIMATION.GALLERY_CAMERA_ROTATION.x,
|
||||
y: ANIMATION.GALLERY_CAMERA_ROTATION.y,
|
||||
z: ANIMATION.GALLERY_CAMERA_ROTATION.z,
|
||||
},
|
||||
{
|
||||
x: ANIMATION.NDS_CAMERA_ROTATION.x,
|
||||
y: ANIMATION.NDS_CAMERA_ROTATION.y,
|
||||
z: ANIMATION.NDS_CAMERA_ROTATION.z,
|
||||
duration:
|
||||
ANIMATION.CAMERA_DURATION *
|
||||
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
||||
delay: 0,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
);
|
||||
@@ -132,8 +147,8 @@ export const useGalleryStore = defineStore("gallery", {
|
||||
{ fadeOpacity: 1 },
|
||||
{
|
||||
fadeOpacity: 0,
|
||||
duration: FADE_DURATION,
|
||||
delay: FADE_DELAY,
|
||||
duration: ANIMATION.FADE_DURATION,
|
||||
delay: fadeDelay,
|
||||
ease: "none",
|
||||
},
|
||||
);
|
||||
@@ -141,7 +156,7 @@ export const useGalleryStore = defineStore("gallery", {
|
||||
setTimeout(() => {
|
||||
this.isOutro = false;
|
||||
app.navigateTo("home");
|
||||
}, 3310);
|
||||
}, ANIMATION.NAVIGATE_DELAY);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user