WebGL Plugin Experimental
GPU-powered slide transitions via raw WebGL. Ships three built-in effects (displacement, RGB-shift, radial) and a custom mode where you supply your own GLSL fragment shader.
Installation
npm install @andresclua/sliderkit-webgl
Import
import { webgl, preloadWebGL } from '@andresclua/sliderkit-webgl'
Usage
import { Slider } from '@andresclua/sliderkit'
import { arrows } from '@andresclua/sliderkit-plugins'
import { webgl, preloadWebGL } from '@andresclua/sliderkit-webgl'
const assets = await preloadWebGL({
slides: [1,2,3,4,5].map(i => `/images/slide-${i}.jpg`),
displacement: '/images/displacement.png',
})
new Slider('#my-slider', {
items: 1,
loop: true,
speed: 0,
plugins: [arrows(), webgl({ effect: 'displacement', assets })],
})
preloadWebGL() options
| Option | Type | Description |
slides | string[] | Image URLs, one per slide in DOM order. |
displacement | string | Optional. Greyscale displacement map URL. Required only for effect: 'displacement'. |
webgl() options
| Option | Type | Default | Description |
effect | 'displacement' | 'rgb-shift' | 'radial' | 'custom' | — | Required. Transition shader to use. |
assets | WebGLAssets | — | Required. Returned by preloadWebGL(). |
duration | number | 900 | Transition length in milliseconds. |
intensity | number | 0.08 | Effect strength. Warp radius for displacement; channel offset for RGB-shift. |
easing | (t: number) => number | cubic ease-in-out | Maps raw progress [0,1] to eased value before it reaches u_progress. |
frag | string | — | Required when effect: 'custom'. Raw GLSL fragment shader source. |
uniforms | Record<string, number | number[] | (() => unknown)> | {} | Extra uniforms injected into the shader each frame. |
Built-in effects
| Effect | Description | Needs displacement map |
displacement | A greyscale map warps both frames simultaneously, producing a fluid ink-wipe. | Yes |
rgb-shift | Splits R and B channels horizontally at mid-transition (chromatic aberration). | No |
radial | Incoming image grows from the centre outward with a soft edge. | No |
Custom shaders
Set effect: 'custom' and provide a GLSL fragment shader via frag. The following uniforms and varying are always available:
| Name | Type | Description |
vUv | varying vec2 | UV coordinates [0,1]. |
u_from | sampler2D | Outgoing slide texture. |
u_to | sampler2D | Incoming slide texture. |
u_progress | float | Eased progress [0,1]. |
u_ar | float | Canvas aspect ratio (width / height). |
u_disp | sampler2D | Displacement map. Only bound when assets.displacement exists. |
webgl({
effect: 'custom',
assets,
frag: `precision mediump float;
varying vec2 vUv;
uniform sampler2D u_from, u_to;
uniform float u_progress, u_ar;
void main() {
float t = smoothstep(0.45, 0.55, vUv.x - u_progress + 0.5);
gl_FragColor = mix(texture2D(u_from, vUv), texture2D(u_to, vUv), t);
}`,
})
Notes
- Only works with
items: 1. The WebGL canvas covers a single slide at a time. - Always set
speed: 0 — the plugin owns the animation, the slider's CSS transition is not used. - The plugin silently no-ops when WebGL is unavailable; the slider still works without the visual effect.
- Sharing an
assets object across multiple sliders is safe — each slider uploads its own GPU textures. - Textures and the WebGL context are released automatically when
slider.destroy() is called.
TypeScript types
import type { WebGLOptions, WebGLAssets, PreloadConfig, BuiltinEffect } from '@andresclua/sliderkit-webgl'
See all effects live in the WebGL demo →