Add magic book catalog block#712
Conversation
miguel-heygen
left a comment
There was a problem hiding this comment.
Cool 3D work — the dissolve + particle vapor effect is genuinely impressive. But based on the team discussion and reviewing the code, this needs structural changes before it fits the catalog.
Catalog fit: showcase vs reusable component
The team aligned on this in the thread: as-is, this is a showcase piece (specific spellbook model, specific magical theme). To be a catalog block — the "shadcn of video components" standard James described — it needs to be generic and model-swappable.
Suggested restructure:
- Rename to
3d-dissolve(orthree-dissolve) — the value is the dissolve effect, not the book - Use HyperFrames variables for the model path, dissolve speed, particle color, and background color. Users should be able to
npx hyperframes add 3d-dissolveand point it at their own GLTF without editing the HTML - Remove the bundled GLTF/textures from the registry — they add ~2MB of binary assets to the repo. Instead, reference a remote URL or document how to bring your own model
- Add instructions in the docs for swapping the model: "Replace
scene.gltfwith your own GLTF model. The dissolve effect adapts to any mesh geometry."
Technical issues
Async timeline construction
The entire composition builds inside an async IIFE (line 79). HyperFrames rule: "Never build timelines inside async/await, setTimeout, or Promises. The capture engine reads window.__timelines synchronously after page load."
The current workaround (register a proxy timeline first, then load GLTF) is fragile. The timeline's onUpdate calls renderAt() which depends on state (bookMesh, gpuCompute, etc.) that doesn't exist until the GLTF loads. If the capture engine seeks before the model loads, it renders an empty scene.
Consider using the Three.js runtime adapter (@hyperframes/three-adapter) which handles async model loading and seek properly. Or use window.__hyperframes_ready to signal when the composition is actually renderable.
Seeded random
The seededRandom() function (mulberry32 variant) is good — deterministic as required. But seed is a let at module scope — if this composition is loaded twice, the second instance shares the mutated seed state. Use a local seed per-instance.
Three.js version
Pinned to three@0.132.2 (2021). The current Three.js is ~0.170+. The legacy examples/js/ imports (GLTFLoader, EffectComposer, etc.) are deprecated in favor of ES module imports. Not blocking, but worth noting for maintainability.
Summary
The VFX quality is great. The path to merging:
- Genericize: rename to
3d-dissolve, add variables for model/colors/speed - Remove bundled binary assets — document bring-your-own-model
- Fix or document the async loading pattern (ideally use the Three.js adapter)
- Verify model-swappability works (Vance's ask)
What
Adds
magic-book, a cinematic 3D spellbook dissolve catalog block with glowing rings, magical dust, and GPGPU particle vaporWhy
This adds a production-style 3D/VFX template to the HyperFrames catalog so users can install it with:
How
Implemented as a standalone registry block under registry/blocks/magic-book.
Notable details:
1.Fixed 1920x1080 composition with 8s duration.
2.Uses a paused GSAP timeline registered as window.__timelines["magic-book"].
3.Preserves deterministic particle placement with seeded randomness.
4.Uses the original GLTF spellbook model, shader dissolve, glowing rings, dust layers, and GPU-driven particles.
5.Waits for the GLTF and particle setup before render capture starts, so HyperFrames render does not capture an empty scene.
6.Adds catalog docs and registry metadata.
Test plan
How was this tested?
Manual validation:
npx hyperframes lint output/magic-book-render-project --verbosenpx hyperframes render output/magic-book-render-project --output output/magic-book-official-preview-fixed5.mp4 --quality draft --fps 24 --workers 1Render output was checked locally to confirm the book, dissolve, glow, and particle effects appear in the captured video.
magic-book-preview.mp4