Plasma UI: WebGL Liquid Panels for React Workspaces

Description:

Plasma UI is a React component library for draggable, liquid-style panels on a shared WebGL canvas.

Panels fuse when they overlap, refract a supplied background, and snap to a grid or neighboring edges when released.

Preview

plasma-ui-webgl-liquid-panels

Features

  • Shared WebGL material for panels that fuse and separate.
  • Dragging with grid and neighbor-edge snapping.
  • tidal, aurora, and ember moods plus custom mood objects.
  • Adjustable refraction, frost, tint, rims, grain, glow, and spring motion.
  • Semantic HTML through as, with ordinary HTML content inside each panel.
  • CSS frosted-panel fallback when WebGL2 is unavailable.
  • Server-rendered fallback markup that changes to the canvas effect after hydration.

How To Use It

Install @cruxgarden/plasma-ui with NPM, Wrap the panel area in PlasmaProvider and put ordinary controls inside each Plasma panel.

In a Next.js App Router project, add "use client" at the top of the component file.

npm install @cruxgarden/plasma-ui
import { PlasmaProvider, Plasma } from "@cruxgarden/plasma-ui";
export function Workspace() {
  return (
    <PlasmaProvider mood="tidal">
      <Plasma as="header" lean={false}>
        Project workspace
      </Plasma>
      <Plasma draggable padding={20}>
        <h2>Inbox</h2>
        <button type="button">Open message</button>
      </Plasma>
    </PlasmaProvider>
  );
}

Dragging and Joining Panels

Set draggable on a panel to move it. It snaps to neighboring edges or the provider grid on release.

onDragEnd receives the settled { x, y } offset, defaultOffset sets an initial position, while offset controls the position from React state.

<Plasma
  draggable
  defaultOffset={{ x: 24, y: 24 }}
  onDragEnd={(offset) => console.log(offset)}
  onJoinChange={(joined) => console.log(joined)}
>
  <h2>Tasks</h2>
  <button data-plasma-nodrag type="button">Add task</button>
</Plasma>

Styling the Material

The provider sets the shared appearance and physics. A panel can override tint, opacity, frost, elevation, radius, and related values.

The built-in moods set color, blend distance, and spring behavior. Set background to a CSS color, image URL, or an image, canvas, or video element.

Keep overlapping dialogs and menus as CSS layers, or use a second provider canvas when they need the plasma material.

<PlasmaProvider
  mood="aurora"
  viscosity={0.6}
  stretch={1.2}
  rimColor="#5fd4ff"
  rimWidth={1.6}
>
  <Plasma tint="#ff5fa2" opacity={0.3} draggable>
    <h2>Player</h2>
  </Plasma>
</PlasmaProvider>

Key Props and Hooks

APIPurpose
PlasmaProvider moodBuilt-in mood name or a custom Mood object.
blendDistance at which panels begin to fuse.
grid, magnet, springShared placement and motion settings.
maxSurfacesVisible panel budget, default 16. Changing it rebuilds shaders.
Plasma draggable, snap, boundsDragging, snap behavior, and drag area.
offset, defaultOffsetControlled or initial panel position.
onDragStart, onDragEnd, onJoinChangeDrag and fusion callbacks.
usePlasmaRuntime()Renderer state, reduced-motion state, pulse(), and bump().

Alternatives and Related Resources

Add Comment