@shader-gallery/react
v0.1.0
Published
React component for shader.gallery animated WebGL backgrounds — one tag, themeable from props.
Readme
@shader-gallery/react
React components for shader.gallery animated WebGL
backgrounds. Two ways in: fetch a shader by slug from the CDN, or bundle one
.frag with your app.
npm install @shader-gallery/react @shader-gallery/runtime<ShaderGalleryBg> — fetch by slug
The default. Renders a <canvas> and drives the shader through
@shader-gallery/runtime (a real React component, not a wrapper around the web
component). The GLSL streams from the CDN by slug at runtime, so your bundle
stays tiny and the catalog can update without a package release.
import { ShaderGalleryBg } from '@shader-gallery/react';
export function Hero() {
return (
<section style={{ position: 'relative', minHeight: '100vh' }}>
<ShaderGalleryBg
slug="nacre"
palette="witchlight"
style={{ position: 'fixed', inset: 0, zIndex: -1 }}
/>
<h1>Backgrounds that glow in the dark</h1>
</section>
);
}Override uniforms and post-FX by name. These retarget the running shader without rebuilding the WebGL context, so they are cheap to drive from state:
function Tunable() {
const [glow, setGlow] = useState(1.0);
return (
<>
<ShaderGalleryBg
slug="nacre"
palette="ember"
uniforms={{ u_glow: glow }}
post={{ bloom: 1.2, grain: 0.15 }}
style={{ position: 'fixed', inset: 0 }}
/>
<input type="range" min={0} max={2} step={0.01}
value={glow} onChange={(e) => setGlow(+e.target.value)} />
</>
);
}An inline
uniforms/postobject is a fresh reference each render and re-runs the apply effect. The write is cheap, butuseMemothe object if you render very often.
Props
| Prop | Type | Notes |
|-------------|---------------------------|-------|
| slug | string | Which shader to load from the CDN. |
| palette | string | Theme name; defaults to the shader's own. Changes live. |
| base | string | Data source URL. Defaults to the production CDN; point at http://localhost:…/ or a Cloudflare tunnel during dev. |
| uniforms | Record<string, number> | Overrides over the shader's defaults, e.g. { u_glow: 1.4 }. Apply live. |
| post | Record<string, number> | Post-FX overrides, e.g. { bloom: 1.2 }. Apply live. |
| frag,meta | string, object | Provide the shader directly instead of fetching by slug (bundled/offline). |
| style,className, … | — | Forwarded to the canvas. Fills its parent by default. |
palette, uniforms and post retarget the running shader without rebuilding
the WebGL context; slug/base/frag remount.
shader() — bundle one frag
The complement to <ShaderGalleryBg>: instead of fetching by slug, this carries
the GLSL with you (offline, versioned, tree-shaken). Each float param becomes a
friendly prop (u_waveSpeed → waveSpeed); palette and post are universal.
A shader.gallery effect is one self-contained .frag with an embedded
/*@shader … */ JSON header. Author your own, or copy the reference effect that
@shader-gallery/components ships on disk at
node_modules/@shader-gallery/components/effects/billow.frag (params
waveSpeed / swell / cross).
import { shader } from '@shader-gallery/react';
import billowSrc from './billow.frag?raw'; // Vite/webpack raw import
const Billow = shader(billowSrc);
export function Background() {
return (
<Billow
waveSpeed={0.6}
swell={420}
palette="opal"
style={{ position: 'fixed', inset: 0 }}
/>
);
}Params apply live, same as uniforms above — wire one to state for a playground:
function Playground() {
const [waveSpeed, setWaveSpeed] = useState(0.35);
return (
<>
<Billow waveSpeed={waveSpeed} palette="midnight" style={{ position: 'fixed', inset: 0 }} />
<input type="range" min={0} max={2} step={0.01}
value={waveSpeed} onChange={(e) => setWaveSpeed(+e.target.value)} />
</>
);
}
./billow.frag?rawis the Vite/webpack way to import a file as a string. On a setup without raw imports, read the file to a string yourself (or in Node, the build step) and pass it toshader()— or use<ShaderGalleryBg frag={…} meta={…} />.
Typed params
shader() returns a loosely-typed component (per-param props are unknown). For
autocomplete on waveSpeed/swell/cross, generate a per-effect .d.ts with
sg-typegen (from @shader-gallery/components) and cast against it:
npx sg-typegen billow.frag --out billow.d.tsimport { shader } from '@shader-gallery/react';
import billowSrc from './billow.frag?raw';
import type { BillowProps } from './billow';
const Billow = shader(billowSrc) as (p: BillowProps) => JSX.Element;
<Billow waveSpeed={0.6} swell={420} cross={0.5} palette="opal" />;SSR
Safe. The component renders a bare <canvas> on the server; the WebGL mount runs
in a client-only effect.
MIT © E. T. Carter · shader.gallery · [email protected]
