PlasmaWave
plasma-waveAnimates two intertwined raymarched plasma ribbons with blended theme colors.
Usage
Basic usage
Put it into the relative overflow-hidden container and fill it with className="absolute inset-0"; the two-color default is chart token with adaptive light and dark.
<div className="relative h-56 overflow-hidden rounded-xl bg-neutral-950">
<PlasmaWave className="absolute inset-0" />
<div className="absolute inset-0 flex items-center justify-center text-white/80">
PlasmaWave
</div>
</div>Oblique rotation + strong focus
rotationDeg The overall rotating wave belt creates oblique tension; focalLength The larger the corrugations are, the more concentrated they are and the deeper they are.
<PlasmaWave className="absolute inset-0" rotationDeg={28} focalLength={1.3} />Hedging flow direction · Warm color
colors Custom two-color; dir2={-1} Let the second ribbon flow in the opposite direction to create a sense of interweaving with the first one.
<PlasmaWave
className="absolute inset-0"
colors={["var(--color-chart-3)", "oklch(0.72 0.22 30)"]}
dir2={-1}
speed1={0.1}
speed2={0.08}
bend1={1.4}
/>Wallpaper-level slow bending
Low speed + large bend makes the ripples slowly rise and fall, as the background of the title area is superimposed under the text.
Hulian component library
Plasma Wave · WebGL · Subject Perception
<div className="relative h-56 overflow-hidden rounded-xl bg-neutral-950">
<PlasmaWave
className="absolute inset-0"
speed1={0.03}
speed2={0.03}
bend1={1.6}
bend2={1.2}
focalLength={0.6}
/>
<div className="absolute inset-0 flex flex-col items-center justify-center gap-2">
<p className="text-lg font-semibold text-white">Hulian Component Library</p>
<p className="text-xs text-white/60">Plasma Wave · WebGL · Subject Perception</p>
</div>
</div>When to Use
Use it for a dense, two-color atmospheric background with interwoven ribbons. Independent speeds, bends, offsets, and rotation support richer compositions than Plasma. For pointer-stirred liquid color, use LiquidEther; for regular geometry, use DotPattern.
Import
import { PlasmaWave } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| colors | string[] | ["var(--color-chart-1)","var(--color-chart-2)"] | CSS color pair; only the first two values are used and token values follow the active theme |
| xOffset | number | 0 | Offset the ribbon horizontally (device pixels), moving the ripple focus away from the center |
| yOffset | number | 0 | Ribbon vertical offset (device pixels) |
| rotationDeg | number | 0 | Overall rotation angle (degrees), arranging transverse wave bands diagonally for more tension |
| focalLength | number | 0.8 | Focal length (sight convergence); the larger, the more concentrated the depth, the smaller the more spread. Recommendation 0.4–1.6 |
| speed1 | number | 0.05 | The flow rate of the first ribbon; the bigger, the faster |
| speed2 | number | 0.05 | Second ribbon flow rate |
| dir2 | number | 1 | Second-ribbon direction: +1 follows the first ribbon and -1 reverses it to emphasize interweaving |
| bend1 | number | 1 | The bending amplitude of the first ribbon; the greater the undulations, the more exaggerated |
| bend2 | number | 0.5 | The bending amplitude of the second ribbon |
| className | string | — | Additional class name for the canvas container or fallback div, often used for sizing, rounding, and opacity |
Slots
| Slot | Type | Description |
|---|---|---|
| fallback | ReactNode | reduced-motion / static alternative content without WebGL; overlaid on top of a static gradient |
Usage Guidelines
- Unlike components of the same family, PlasmaWave does not come with its own positioning class. You must pass
className="absolute inset-0"yourself to cover therelativeparent container, and useabsolute inset-0/relative z-10[[webgl-canvas-rendered-but-invisible-negative-zindex-covered]] for overlay content. - WebGL client component (
"use client"); only fallback is rendered during the SSR phase. colorsis parsed by off-screen canvas when passingvar(--color-…), must be prefixed with `--color-`, and the parsing of barevar(--primary)fails with [[oklch-css-var-color-must-parse-via-offscreen-canvas]].- Headless screenshots can capture a still or blank frame when rAF is throttled. Verify motion on a real device or with Playwright measurements; see [[recharts-headless-screenshot-blank-clippath-animation-starved]].
Related
DotPattern · GridPattern · StripedPattern · Spotlight · RetroGrid · Ripple
Playground
<div className="relative h-56 overflow-hidden rounded-xl"
style={{ background: "oklch(0.14 0.02 280)" }}>
<PlasmaWave
className="absolute inset-0"
rotationDeg={0}
focalLength={0.8}
speed1={0.05}
speed2={0.05}
bend1={1}
bend2={0.5}
/>
</div>