feat: implement suspense-based alpha tracing for token meshes

Refactor `TokenMesh` to use a custom `useTrace` hook that suspends
during the alpha channel tracing process. This allows the `Bounds`
component in `Scene` to correctly fit the camera to the token's
geometry once it has been fully loaded and traced.
This commit is contained in:
2026-08-08 17:54:43 +08:00
parent 55e0351c1d
commit b6bd4612e0
3 changed files with 49 additions and 32 deletions
+8 -2
View File
@@ -1,6 +1,6 @@
import { Suspense, type ReactNode } from 'react';
import { Canvas } from '@react-three/fiber';
import { ContactShadows, OrbitControls } from '@react-three/drei';
import { Bounds, ContactShadows, OrbitControls } from '@react-three/drei';
import { Bloom, EffectComposer, Vignette } from '@react-three/postprocessing';
/**
@@ -8,6 +8,10 @@ import { Bloom, EffectComposer, Vignette } from '@react-three/postprocessing';
* lighting, orbit controls, a soft contact shadow, and subtle post-processing
* (bloom + vignette). Children are wrapped in a Suspense boundary so loading
* assets (textures, models) can suspend without blanking the page.
*
* The camera is fitted to the bounds of the content on mount. `Bounds` sits
* inside the Suspense boundary, so it only mounts once the (suspending) content
* has loaded and its geometry is present.
*/
export default function Scene({ children }: { children: ReactNode }) {
return (
@@ -22,7 +26,9 @@ export default function Scene({ children }: { children: ReactNode }) {
<directionalLight position={[-4, 2, -3]} intensity={0.4} color="#b3c7ff" />
<pointLight position={[0, 3, 0]} intensity={0.3} />
<Suspense fallback={null}>{children}</Suspense>
<Suspense fallback={null}>
<Bounds>{children}</Bounds>
</Suspense>
<ContactShadows
position={[0, -0.5, 0]}