shader-bg
v0.0.3
Published
Lightweight WebGL shader background renderer for the browser.
Downloads
390
Maintainers
Readme
shader-bg
Lightweight WebGL shader background renderer for the browser.
shader-bg creates or reuses a <canvas>, compiles your shaders, updates common uniforms every frame, and renders a full-screen shader animation.
Install
npm install shader-bgQuick start
import { ShaderBg } from 'shader-bg';
const bg = new ShaderBg(document.body, {
fragmentShader: `
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
gl_FragColor = vec4(uv.x, uv.y, abs(sin(u_time)), 1.0);
}
`,
});
bg.start();To fully clean up (RAF loop, observers, WebGL resources, optional auto-created canvas):
bg.dispose();API
new ShaderBg(target, options)
Creates the renderer instance.
target:string | HTMLElement | Element- CSS selector string (for example:
"#hero") - Existing element or canvas
- If
targetis not a canvas, a canvas is created and appended to it
- CSS selector string (for example:
options:OptionsInput- Configuration for shaders, uniforms, canvas attributes/styles, and backbuffer
Methods
start()- starts the render loopstop()- stops the render loopdispose()- releases resources and detaches observers/listeners
Options
type UniformValue = number | number[] | WebGLTexture;
type UniformValueSetter = UniformValue | (() => UniformValue);
interface BackbufferOptionsInput {
enabled?: boolean;
uniformName?: string;
}
interface OptionsInput {
vertexShader?: string;
fragmentShader?: string;
canvas?: {
class?: string;
id?: string;
style?: Partial<CSSStyleDeclaration>;
};
uniforms?: Record<string, UniformValueSetter>;
backbuffer?: boolean | BackbufferOptionsInput;
}Option details
vertexShader(string)- Custom vertex shader source
- Default: built-in pass-through vertex shader (
attribute vec2 position)
fragmentShader(string)- Fragment shader source
- Default: built-in solid red fragment shader
canvas.class(string)- Extra class name(s) added to the render canvas
canvas.id(string)- Optional
idset on the canvas
- Optional
canvas.style(Partial<CSSStyleDeclaration>)- Inline style object merged into canvas style
uniforms(Record<string, UniformValueSetter>)- Additional uniforms set each frame
- Value can be static or a function returning current value
backbuffer(boolean | { enabled?: boolean; uniformName?: string })- Enables previous-frame texture capture
trueis equivalent to{ enabled: true }uniformNamedefault:"u_backbuffer"
Built-in uniforms
These uniforms are updated automatically every frame:
u_time: float- seconds since instance creationu_resolution: vec2- current canvas width/height in pixelsu_mouse: vec2- pointer position normalized to[0..1]u_scroll: vec2- page scroll progress values
If backbuffer is enabled:
u_backbuffer(or your customuniformName) as asampler2D
Examples
1) Target by selector + custom canvas styling
import { ShaderBg } from 'shader-bg';
const bg = new ShaderBg('#hero', {
fragmentShader: `
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
float v = 0.5 + 0.5 * sin(u_time + uv.x * 8.0);
gl_FragColor = vec4(vec3(v), 1.0);
}
`,
canvas: {
class: 'shader-bg-canvas',
id: 'hero-shader',
style: {
position: 'absolute',
inset: '0',
width: '100%',
height: '100%',
zIndex: '-1',
},
},
});
bg.start();2) Dynamic custom uniforms
import { ShaderBg } from 'shader-bg';
const bg = new ShaderBg(document.body, {
fragmentShader: `
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
uniform vec3 u_color;
uniform float u_strength;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
float pulse = 0.5 + 0.5 * sin(u_time * 2.0);
gl_FragColor = vec4(u_color * pulse * u_strength, 1.0);
}
`,
uniforms: {
u_color: [0.2, 0.7, 1.0],
u_strength: () => 0.6 + 0.4 * Math.sin(performance.now() * 0.001),
},
});
bg.start();3) Backbuffer feedback effect
import { ShaderBg } from 'shader-bg';
const bg = new ShaderBg('#app', {
fragmentShader: `
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;
uniform sampler2D u_backbuffer;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
vec3 prev = texture2D(u_backbuffer, uv).rgb;
vec3 next = 0.98 * prev + 0.02 * vec3(
0.5 + 0.5 * sin(u_time + uv.x * 10.0),
0.5 + 0.5 * sin(u_time + uv.y * 10.0),
0.5 + 0.5 * sin(u_time)
);
gl_FragColor = vec4(next, 1.0);
}
`,
backbuffer: true,
});
bg.start();Custom backbuffer uniform name:
const bg = new ShaderBg('#app', {
fragmentShader: '...',
backbuffer: {
enabled: true,
uniformName: 'u_prevFrame',
},
});Notes
- Works in browsers with WebGL support (
canvas.getContext('webgl')). - Canvas size is synced from
canvas.clientWidth/canvas.clientHeight. - If you pass a container element, dispose removes only the auto-created canvas.
- For a minimal setup, pass
{}as options and provide only what you need.
Development
npm install
npm run dev
npm run build