Semantic bloom
TypographyA living wordmark whose particles wander, connect and gather into a liquid organism. Adapted from ThreeUI with Cojeev colors and motion controls.
Try it
Add to your project
npx shadcn@latest add https://luv-jeri.github.io/cojeev-ui/r/semantic-bloom.jsonThe command includes the component’s shared dependencies. Your project keeps editable source files.
Include the complete example
This example also composes button, input, label, slider, native-select, switch, typography. Install its parts together:
npx shadcn@latest add https://luv-jeri.github.io/cojeev-ui/r/semantic-bloom.json https://luv-jeri.github.io/cojeev-ui/r/button.json https://luv-jeri.github.io/cojeev-ui/r/input.json https://luv-jeri.github.io/cojeev-ui/r/label.json https://luv-jeri.github.io/cojeev-ui/r/slider.json https://luv-jeri.github.io/cojeev-ui/r/native-select.json https://luv-jeri.github.io/cojeev-ui/r/switch.json https://luv-jeri.github.io/cojeev-ui/r/typography.jsonUsing semantic bloom
Use text for a readable DOM wordmark. Choose tone="signature", "memory", "together" or "ink"; colors follow the surrounding design tokens. The host has a default minimum height and accepts className/style.
Tune physics: particleCount (8–100), radius (6–28), speed (0–2), wander (0–1), damping (0.8–0.98), pointerAttraction (0–3), pointerRadius (0–600), textAttraction (0–3), textRadius (0–400), connectionDistance (0–240). Distances are CSS pixels. Invalid numeric values fall back to safe defaults.
Tune size (0.55–1.6), opacity (0–1, artwork only), softness (0–20), edgeTexture (0–40), and connectionWidth (0–8). Zero connection width removes links. Very small particles with a large blur can dissolve; reduce softness to expose individual particles.
Pass controlsRef for gather(), scatter() and reset(); connect these to native buttons or real application events. seed provides a repeatable initial arrangement. onWordActive reports decorative proximity only, not semantic analysis.
Source-based adaptation of ThreeUI Semantic Bloom (MIT, copyright 2026 Meng To). Original force defaults and liquid filter retained; native container coordinates, fixed 60Hz simulation, palette and lifecycle replace the iframe. See docs/semantic-bloom.md and reference/semantic-bloom for attribution and a runnable baseline.
API
Compose the exported parts below. The prop types are read from the React source during the registry build.
Native element or underlying primitive props are inherited where declared, including accessible labels, event handlers and refs.
SemanticBloomProps
| Prop | Type | Required |
|---|---|---|
textReadable DOM wordmark. Whitespace and long text wrap naturally. | string | No |
toneCojeev color presets. Inherits the surrounding light/dark theme. | "signature" | "memory" | "together" | "ink" | No |
sizeWordmark scale, 0.55–1.6. | number | No |
opacityCanvas opacity, 0–1; text always remains readable. | number | No |
pausedFreeze decorative movement and pointer response. | boolean | No |
interactiveEnable local pointer attraction without capturing scroll or clicks. | boolean | No |
physicsEditable simulation forces, distances and density. | BloomOptions | No |
softnessLiquid edge blur, 0–20 CSS pixels. Default 12 (upstream). | number | No |
edgeTextureOrganic edge displacement, 0–40. Default 20 (upstream). | number | No |
connectionWidthConnection stroke width, 0–8 CSS pixels. Default 4. | number | No |
seedRepeatable initial particle arrangement. | number | No |
controlsRefImperative commands for native buttons or application events. | React.Ref<SemanticBloomControls> | No |
onWordActiveOptional decorative word proximity event; does not represent semantic understanding. | (word: string, index: number) => void | No |
Accessibility
The complete wordmark is selectable, wrapping DOM text. The canvas/filter/fallback are decorative and hidden from assistive technology. Essential meaning must not depend on particles or onWordActive.
Provide a Pause button for an ongoing animation. paused, speed=0, system reduced motion, Motion Off, Flow Off, hidden tabs and offscreen hosts suspend continuous rendering. Direct gather/scatter/reset controls remain available; no essential action requires hovering.
Pointer tracking stays local, leaves the cursor visible and releases on leave/cancel/touch end. Touch retains vertical scrolling. Context failure keeps a static organic fallback and readable text.
Particle count, DPR, canvas area and catch-up steps are bounded. Resize observers, theme/font listeners and animation frames are disposed on unmount. This example is an interactive visual demo, not connected agent activity.
States and appearance
For conditional content, keep a MotionPresence boundary around keyed MotionSurface children. The shared entrance and exit states work with native primitives and respect your motion preference.
Try pointer and keyboard interaction, and switch the appearance control in the navigation to compare light and dark mode. Motion respects reduced motion preferences.