feat(2d-nds): intro animation
This commit is contained in:
@@ -5,7 +5,6 @@ const store = useIntroStore();
|
|||||||
const frames = Object.keys(assets.images.intro.logoAnimated).sort();
|
const frames = Object.keys(assets.images.intro.logoAnimated).sort();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.$reset();
|
|
||||||
store.animateIntro();
|
store.animateIntro();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,38 @@ const app = useAppStore();
|
|||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
const hintsContainer = useTemplateRef("hintsContainer");
|
const hintsContainer = useTemplateRef("hintsContainer");
|
||||||
|
|
||||||
|
const { assets } = useAssets();
|
||||||
|
|
||||||
|
const introState = reactive({
|
||||||
|
scaleMultiplier: 1,
|
||||||
|
rotateX: 0,
|
||||||
|
rotateY: 0,
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
let introPlayed = false;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (app.booted || app.settings.renderingMode !== "2d" || introPlayed) return;
|
||||||
|
introPlayed = true;
|
||||||
|
|
||||||
|
introState.scaleMultiplier = 0.6;
|
||||||
|
introState.rotateX = 70;
|
||||||
|
introState.rotateY = 0;
|
||||||
|
introState.opacity = 0;
|
||||||
|
|
||||||
|
assets.audio.whoosh.play();
|
||||||
|
|
||||||
|
gsap.to(introState, {
|
||||||
|
scaleMultiplier: 1,
|
||||||
|
rotateX: 0,
|
||||||
|
rotateY: 360,
|
||||||
|
opacity: 1,
|
||||||
|
duration: 2.8,
|
||||||
|
ease: "power2.inOut",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const buttonsDown = reactive(new Set<string>());
|
const buttonsDown = reactive(new Set<string>());
|
||||||
let mousePressedButton: string | null = null;
|
let mousePressedButton: string | null = null;
|
||||||
|
|
||||||
@@ -72,10 +104,19 @@ const ndsScale = computed(() => {
|
|||||||
const gallery = useGalleryStore();
|
const gallery = useGalleryStore();
|
||||||
const TOP_SCREEN_OFFSET = 170;
|
const TOP_SCREEN_OFFSET = 170;
|
||||||
|
|
||||||
const zoomStyle = computed(() => {
|
const ndsStyle = computed(() => {
|
||||||
const scale = ndsScale.value * gallery.zoom.scale;
|
const scale =
|
||||||
|
ndsScale.value * gallery.zoom.scale * introState.scaleMultiplier;
|
||||||
const y = TOP_SCREEN_OFFSET * ndsScale.value * (gallery.zoom.scale - 1);
|
const y = TOP_SCREEN_OFFSET * ndsScale.value * (gallery.zoom.scale - 1);
|
||||||
return { transform: `translateY(${y}px) scale(${scale})` };
|
return {
|
||||||
|
transform: `translateY(${y}px) scale(${scale}) rotateX(${introState.rotateX}deg) rotateY(${introState.rotateY}deg)`,
|
||||||
|
opacity: introState.opacity,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const showBackFace = computed(() => {
|
||||||
|
const r = ((introState.rotateY % 360) + 360) % 360;
|
||||||
|
return r > 90 && r < 270;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -102,8 +143,9 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="nds2d-container">
|
<div class="nds2d-container">
|
||||||
<div class="nds2d" :style="zoomStyle">
|
<div class="nds2d" :style="ndsStyle">
|
||||||
<div class="nds2d-top-screen">
|
<div v-if="showBackFace" class="nds2d-top-screen"></div>
|
||||||
|
<div v-else 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>
|
||||||
<div class="nds2d-screen nds2d-screen-top">
|
<div class="nds2d-screen nds2d-screen-top">
|
||||||
@@ -113,10 +155,11 @@ watch(
|
|||||||
<div class="nds2d-speaker-hole nds2d-sh4"></div>
|
<div class="nds2d-speaker-hole nds2d-sh4"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nds2d-hinge">
|
<div class="nds2d-hinge">
|
||||||
<div class="nds2d-mic"></div>
|
<div v-if="!showBackFace" class="nds2d-mic"></div>
|
||||||
<div class="nds2d-light"></div>
|
<div v-if="!showBackFace" class="nds2d-light"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nds2d-bottom-screen">
|
<div v-if="showBackFace" class="nds2d-bottom-screen"></div>
|
||||||
|
<div v-else class="nds2d-bottom-screen">
|
||||||
<div class="nds2d-screen nds2d-screen-bottom">
|
<div class="nds2d-screen nds2d-screen-bottom">
|
||||||
<slot name="bottomScreen" />
|
<slot name="bottomScreen" />
|
||||||
</div>
|
</div>
|
||||||
@@ -246,6 +289,7 @@ watch(
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
background: #181818;
|
background: #181818;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
perspective: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nds2d {
|
.nds2d {
|
||||||
@@ -271,6 +315,7 @@ watch(
|
|||||||
0px -1px 2px 2px #111;
|
0px -1px 2px 2px #111;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nds2d-screen {
|
.nds2d-screen {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 51.5%;
|
width: 51.5%;
|
||||||
|
|||||||
@@ -14,15 +14,17 @@ export const useIntroStore = defineStore("intro", {
|
|||||||
|
|
||||||
isIntro: true,
|
isIntro: true,
|
||||||
isOutro: false,
|
isOutro: false,
|
||||||
|
isAnimating: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
animateIntro() {
|
animateIntro() {
|
||||||
|
if (this.isAnimating) return;
|
||||||
|
this.isAnimating = true;
|
||||||
this.isIntro = true;
|
this.isIntro = true;
|
||||||
|
|
||||||
const { assets } = useAssets();
|
const { assets } = useAssets();
|
||||||
const app = useAppStore();
|
const delay = 3;
|
||||||
const delay = app.settings.renderingMode === "2d" ? 1 : 3;
|
|
||||||
const totalFrames = Object.keys(assets.images.intro.logoAnimated).length;
|
const totalFrames = Object.keys(assets.images.intro.logoAnimated).length;
|
||||||
const logoDuration = totalFrames / 25;
|
const logoDuration = totalFrames / 25;
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ export const useIntroStore = defineStore("intro", {
|
|||||||
.timeline({
|
.timeline({
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
this.isIntro = false;
|
this.isIntro = false;
|
||||||
|
this.isAnimating = false;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.call(
|
.call(
|
||||||
|
|||||||
Reference in New Issue
Block a user