Skip to content

Commit

Permalink
feat(ghostModal): click to start and option to restart animation (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
wopian committed Jun 25, 2023
1 parent 9b3c016 commit 9ed456f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 14 deletions.
78 changes: 68 additions & 10 deletions src/components/canvases/GhostCanvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@
ground,
grid
} = createGhostScene()
const { ghosts, totalDuration } = await createGhosts(scene, ghostUrls)
const hasStartedAnimating = ref(false)
const hasFinishedAnimating = ref(false)
const loadedGhosts = ref(0)
const { ghosts, totalDuration } = await createGhosts(
scene,
ghostUrls,
loadedGhosts
)
let longestGhost = ghosts[0]
for (const ghost of ghosts) {
Expand Down Expand Up @@ -73,17 +82,15 @@
directionalLight.position.y += 50
ground.position.copy(center)
ground.position.y = 0
ground.position.y = -4
grid.position.copy(center)
grid.position.y = 0.01
grid.position.y = -4
if (IS_DEV) {
stats = new Stats()
document.body.append(stats.dom)
}
animate()
})
onUnmounted(() => {
Expand All @@ -92,10 +99,7 @@
})
const animateDrawing = () => {
const elapsedTime = clock.getElapsedTime()
currentTime.value =
longestGhost.ghost.frames[0].time +
(elapsedTime / totalDuration) * totalDuration
currentTime.value = clock.getElapsedTime()
while (
currentFrame < longestGhost.ghost.frames.length - 1 &&
Expand Down Expand Up @@ -143,6 +147,7 @@
const hasNextFrame = currentFrame < longestGhost.ghost.frames.length - 1
if (hasNextFrame) animateDrawing()
else hasFinishedAnimating.value = true
controls.enableZoom = true
controls.enableRotate = true
Expand All @@ -156,16 +161,51 @@
requestAnimationFrame(animate)
}
const onStart = () => {
if (hasStartedAnimating.value) return
hasStartedAnimating.value = true
animate()
}
const onReplay = () => {
clock.startTime = 0
clock.elapsedTime = 0
currentFrame = 0
currentTime.value = 0
for (const { geometry, material } of ghosts) {
material.visible = false
geometry.setDrawRange(0, 0)
}
onStart()
}
</script>

<template>
<div>{{ formatResultTime(currentTime) }}</div>

<div v-if="!ghosts" :class="$style.preloader">
Loading {{ loadedGhosts + 1 }} of {{ ghostUrls.length }} ghosts
</div>
<div v-else-if="!hasStartedAnimating" :class="$style.preloader">
<div>{{ ghostUrls.length }} ghosts initialised</div>
<div>Following the white soapbox</div>
<button @click="onStart">Start Replay</button>
</div>
<div v-else-if="hasFinishedAnimating" :class="$style.replay">
<button @click="onReplay">Replay</button>
</div>

<div ref="containerRef" :class="$style.container"></div>
</template>

<style module lang="less">
.preloader,
.container {
z-index: -1;
width: 100%;
height: 100%;
Expand All @@ -175,4 +215,22 @@
right: 0;
bottom: 0;
}
.container {
z-index: -1;
}
.preloader {
display: flex;
flex-direction: column;
justify-content: center;
place-content: center;
align-items: center;
text-align: center;
gap: 1rem;
button {
cursor: pointer;
}
}
</style>
4 changes: 2 additions & 2 deletions src/components/modals/GhostModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</button>
<div v-if="isOpen" :class="$style.modal">
<h1>Ghost Explorer (ALPHA)</h1>
<button @click="onClose"><icon-x /></button>
<button :class="$style.close" @click="onClose"><icon-x /></button>
<ghost-canvas :ghost-urls="ghostUrls" />
</div>
</template>
Expand Down Expand Up @@ -67,7 +67,7 @@
height: unset;
}
button {
button.close {
position: absolute;
top: 1rem;
right: 1rem;
Expand Down
13 changes: 11 additions & 2 deletions src/utils/three/createGhosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
Vector3
} from 'three'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'
import { type Ref } from 'vue'

import soapboxUrl from '~/assets/models/combined_soapbox.stl?url'

interface GhostInstance {
export interface GhostInstance {
ghost: Ghost
points: Vector3[]
curve: CatmullRomCurve3
Expand All @@ -23,7 +24,11 @@ interface GhostInstance {
soapbox?: Mesh
}

export const createGhosts = async (scene: Scene, urls: string[]) => {
export const createGhosts = async (
scene: Scene,
urls: string[],
loadedGhosts: Ref<number>
) => {
const ghosts: (GhostInstance | undefined)[] = []

let totalDuration = 0
Expand All @@ -38,6 +43,8 @@ export const createGhosts = async (scene: Scene, urls: string[]) => {
)
ghosts.push(undefined)
continue
} else {
console.log(`Ghost ${index} uses version ${ghost.version}`)
}

totalDuration = Math.max(totalDuration, ghost.frames.at(-1)?.time ?? 0)
Expand Down Expand Up @@ -85,6 +92,8 @@ export const createGhosts = async (scene: Scene, urls: string[]) => {

scene.add(line)

loadedGhosts.value++

ghosts.push({
ghost,
points,
Expand Down

0 comments on commit 9ed456f

Please sign in to comment.