feat(2d-nds): animation to and from gallery
This commit is contained in:
@@ -55,6 +55,17 @@ const ndsScale = computed(() => {
|
|||||||
return Math.min(scaleX, scaleY);
|
return Math.min(scaleX, scaleY);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const gallery = useGalleryStore();
|
||||||
|
const TOP_SCREEN_OFFSET = 170;
|
||||||
|
|
||||||
|
const zoomStyle = computed(() => {
|
||||||
|
const scale = ndsScale.value * gallery.zoom.scale;
|
||||||
|
if (scale === 1) return { scale: ndsScale.value };
|
||||||
|
|
||||||
|
const y = TOP_SCREEN_OFFSET * ndsScale.value * (gallery.zoom.scale - 1);
|
||||||
|
return { transform: `translateY(${y}px) scale(${scale})` };
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => app.hintsVisible,
|
() => app.hintsVisible,
|
||||||
async (show) => {
|
async (show) => {
|
||||||
@@ -75,13 +86,11 @@ watch(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
defineExpose({ ndsScale });
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="nds2d-container">
|
<div class="nds2d-container">
|
||||||
<div class="nds2d" :style="{ scale: ndsScale }">
|
<div class="nds2d" :style="zoomStyle">
|
||||||
<div class="nds2d-top-screen">
|
<div class="nds2d-top-screen">
|
||||||
<div class="nds2d-speaker-hole nds2d-sh1"></div>
|
<div class="nds2d-speaker-hole nds2d-sh1"></div>
|
||||||
<div class="nds2d-speaker-hole nds2d-sh2"></div>
|
<div class="nds2d-speaker-hole nds2d-sh2"></div>
|
||||||
@@ -204,6 +213,7 @@ defineExpose({ ndsScale });
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: #181818;
|
background: #181818;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nds2d {
|
.nds2d {
|
||||||
|
|||||||
@@ -2,16 +2,22 @@ import gsap from "gsap";
|
|||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
|
||||||
const ANIMATION = {
|
const ANIMATION = {
|
||||||
|
FADE_DURATION: 1,
|
||||||
|
FADE_CAMERA_OVERLAP: 0.9,
|
||||||
|
NAVIGATE_DELAY: 3150,
|
||||||
|
|
||||||
|
// 3D zoom
|
||||||
NDS_CAMERA_POSITION: new THREE.Vector3(0, 14, 10),
|
NDS_CAMERA_POSITION: new THREE.Vector3(0, 14, 10),
|
||||||
NDS_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-55), 0, 0),
|
NDS_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-55), 0, 0),
|
||||||
GALLERY_CAMERA_POSITION: new THREE.Vector3(0, 4.5, -3),
|
GALLERY_CAMERA_POSITION: new THREE.Vector3(0, 4.5, -3),
|
||||||
GALLERY_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-62), 0, 0),
|
GALLERY_CAMERA_ROTATION: new THREE.Euler(THREE.MathUtils.degToRad(-62), 0, 0),
|
||||||
|
|
||||||
CAMERA_DURATION: 3,
|
CAMERA_DURATION: 3,
|
||||||
CAMERA_ROTATION_OVERLAP: 0.1,
|
CAMERA_ROTATION_OVERLAP: 0.1,
|
||||||
FADE_DURATION: 1,
|
|
||||||
FADE_CAMERA_OVERLAP: 0.9,
|
// 2D zoom
|
||||||
NAVIGATE_DELAY: 3150,
|
ZOOM_SCALE: 6,
|
||||||
|
ZOOM_DURATION: 3,
|
||||||
|
ZOOM_EASE: "power2.inOut",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGalleryStore = defineStore("gallery", {
|
export const useGalleryStore = defineStore("gallery", {
|
||||||
@@ -24,6 +30,10 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
fadeOpacity: 1,
|
fadeOpacity: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
zoom: {
|
||||||
|
scale: 1,
|
||||||
|
},
|
||||||
|
|
||||||
isIntro: true,
|
isIntro: true,
|
||||||
isOutro: false,
|
isOutro: false,
|
||||||
shouldAnimateOutro: false,
|
shouldAnimateOutro: false,
|
||||||
@@ -37,9 +47,8 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
const app = useAppStore();
|
const app = useAppStore();
|
||||||
app.disallowHints();
|
app.disallowHints();
|
||||||
|
|
||||||
// Intro: Fade starts first (at 0), camera starts after with overlap
|
// Intro: Fade starts first (at 0), camera/zoom starts after with overlap
|
||||||
const cameraDelay =
|
const zoomDelay = ANIMATION.FADE_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
||||||
ANIMATION.FADE_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
|
||||||
|
|
||||||
gsap.fromTo(
|
gsap.fromTo(
|
||||||
this.intro,
|
this.intro,
|
||||||
@@ -65,8 +74,8 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
y: ANIMATION.GALLERY_CAMERA_POSITION.y,
|
y: ANIMATION.GALLERY_CAMERA_POSITION.y,
|
||||||
z: ANIMATION.GALLERY_CAMERA_POSITION.z,
|
z: ANIMATION.GALLERY_CAMERA_POSITION.z,
|
||||||
duration: ANIMATION.CAMERA_DURATION,
|
duration: ANIMATION.CAMERA_DURATION,
|
||||||
delay: cameraDelay,
|
delay: zoomDelay,
|
||||||
ease: "power2.inOut",
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -84,8 +93,19 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
duration:
|
duration:
|
||||||
ANIMATION.CAMERA_DURATION *
|
ANIMATION.CAMERA_DURATION *
|
||||||
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
||||||
delay: cameraDelay,
|
delay: zoomDelay,
|
||||||
ease: "power2.inOut",
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
gsap.fromTo(
|
||||||
|
this.zoom,
|
||||||
|
{ scale: 1 },
|
||||||
|
{
|
||||||
|
scale: ANIMATION.ZOOM_SCALE,
|
||||||
|
duration: ANIMATION.ZOOM_DURATION,
|
||||||
|
delay: zoomDelay,
|
||||||
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -102,7 +122,7 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
|
|
||||||
const app = useAppStore();
|
const app = useAppStore();
|
||||||
|
|
||||||
// Outro: Camera starts first (at 0), fade starts after with overlap
|
// Outro: Camera/zoom starts first (at 0), fade starts after with overlap
|
||||||
const fadeDelay =
|
const fadeDelay =
|
||||||
ANIMATION.CAMERA_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
ANIMATION.CAMERA_DURATION - ANIMATION.FADE_CAMERA_OVERLAP;
|
||||||
|
|
||||||
@@ -120,7 +140,7 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
z: ANIMATION.NDS_CAMERA_POSITION.z,
|
z: ANIMATION.NDS_CAMERA_POSITION.z,
|
||||||
duration: ANIMATION.CAMERA_DURATION,
|
duration: ANIMATION.CAMERA_DURATION,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
ease: "power2.inOut",
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -139,7 +159,18 @@ export const useGalleryStore = defineStore("gallery", {
|
|||||||
ANIMATION.CAMERA_DURATION *
|
ANIMATION.CAMERA_DURATION *
|
||||||
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
(1 - ANIMATION.CAMERA_ROTATION_OVERLAP),
|
||||||
delay: 0,
|
delay: 0,
|
||||||
ease: "power2.inOut",
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
gsap.fromTo(
|
||||||
|
this.zoom,
|
||||||
|
{ scale: ANIMATION.ZOOM_SCALE },
|
||||||
|
{
|
||||||
|
scale: 1,
|
||||||
|
duration: ANIMATION.ZOOM_DURATION,
|
||||||
|
delay: 0,
|
||||||
|
ease: ANIMATION.ZOOM_EASE,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user