gpuslider: GPU Image & Video Carousel with Shader Effects

Category: Javascript , Slider | October 8, 2026
Authorniklasp
Last UpdateOctober 8, 2026
LicenseMIT
Views0 views
gpuslider: GPU Image & Video Carousel with Shader Effects

gpuslider is a dependency-free JavaScript carousel library for image and video sliders with GPU-rendered shader effects. Slides can stretch, bend, split into color channels, or switch through liquid and glitch transitions.

It keeps real HTML slides on the page and falls back to browser-rendered media when GPU rendering is unavailable. A CDN entry initializes sliders from HTML attributes, and modular JavaScript imports are available for custom projects.

Features

  • A 4.7 KB gzipped core with optional plugins.
  • 20+ GPU effects driven by motion, position, and pointer input.
  • 20+ transitions for stacked slides and multi-pane galleries.
  • Mouse dragging, touch swiping, wheel input, and keyboard navigation.
  • Horizontal and vertical movement, looping, and free scrolling.
  • Optional autoplay, thumbnail navigation, pagination, and lightbox.
  • Responsive sizing and spacing through CSS custom properties.
  • Loading-screen and adaptive canvas-quality plugins.
  • TypeScript declarations and React components for server-rendered pages.
  • Reduced-motion behavior and ARIA-aware navigation controls.
  • Custom GLSL effects shared by WebGPU and WebGL 2 renderers.

How To Use It

Installation

Load the stylesheet and the module-based auto initializer from a CDN. This initializes elements with data-gs and loads the GPU renderer only when required.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gpuslider@1/dist/style.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/gpuslider@1/dist/auto.js"></script>

Or install the package via npm.

npm install gpuslider

For a lightbox or loading screen, import the extra stylesheet for the feature that is enabled. A standard carousel only needs style.css.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gpuslider@1/dist/lightbox.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gpuslider@1/dist/loading.css">

Basic Usage

The CDN method accepts slider options as JSON in data-gs. The data-gs-canvas attribute activates the GPU canvas and selects its effects.

<div class="gs" aria-label="Photo gallery"
     data-gs='{"loop":true}'
     data-gs-canvas="stretch waves">
  <div class="gs-track">
    <div class="gs-slide">
      <img class="gs-media" src="photo-1.jpg" alt="Mountain lake">
    </div>
    <div class="gs-slide">
      <img class="gs-media" src="photo-2.jpg" alt="Coastal cliffs">
    </div>
    <div class="gs-slide">
      <img class="gs-media" src="photo-3.jpg" alt="Forest trail">
    </div>
    <div class="gs-slide">
      <img class="gs-media" src="photo-4.jpg" alt="Sunset beach">
    </div>
    <div class="gs-slide">
      <img class="gs-media" src="photo-5.jpg" alt="Desert dunes">
    </div>
  </div>
  <button data-gs-prev aria-label="Previous slide">&#8249;</button>
  <button data-gs-next aria-label="Next slide">&#8250;</button>
  <div data-gs-dots></div>
</div>

Give the slides a defined height or aspect ratio to reserve space before media loading. The number of visible slides and the gap between them come from CSS.

.gs {
  --gs-per-view: 1.2;
  --gs-gap: 12px;
}
.gs-slide { aspect-ratio: 16 / 9; }
@media (min-width: 960px) {
  .gs { --gs-per-view: 3; }
}

Initialize With JavaScript

Use the core entry when you want to import only the features your carousel needs. The canvas plugin accepts an ordered array of shader effects.

import { createSlider } from 'gpuslider';
import { controls, keyboard } from 'gpuslider/plugins';
import { canvas } from 'gpuslider/canvas';
import { stretch, split } from 'gpuslider/effects';
import 'gpuslider/style.css';
const slider = createSlider(document.querySelector('.gs'), {
  loop: true,
  plugins: [
    controls(),
    keyboard(),
    canvas({ effects: [stretch(), split()] })
  ]
});

The gpuslider/full entry includes controls, keyboard and wheel input, autoplay, auto height, and stacked layouts through additional options. For mode: 'stack', place gs-stack on the HTML root before JavaScript loads. Use the stacked markup in the next example.

import { createSlider } from 'gpuslider/full';
import { canvas } from 'gpuslider/canvas';
import { liquid } from 'gpuslider/effects';
import 'gpuslider/style.css';
createSlider(document.querySelector('.gs-stack'), {
  mode: 'stack',
  loop: true,
  autoplay: 4000,
  plugins: [canvas({ effects: [liquid()] })]
});

Create Shader Transitions

Transitions operate on stacked slides. Reserve slide space with CSS or image dimensions before initialization. A stacked slider displays its first slide when JavaScript is disabled; the other slides are not available through native scrolling.

<div class="gs gs-stack" aria-label="Featured photos">
  <div class="gs-track">
    <div class="gs-slide"><img class="gs-media" src="one.jpg" alt="Photo one"></div>
    <div class="gs-slide"><img class="gs-media" src="two.jpg" alt="Photo two"></div>
    <div class="gs-slide"><img class="gs-media" src="three.jpg" alt="Photo three"></div>
  </div>
</div>

For a modular setup, use stack() and a transition such as burn(). A stack fades between slides when no GPU transition is active.

import { createSlider } from 'gpuslider';
import { stack, controls } from 'gpuslider/plugins';
import { canvas } from 'gpuslider/canvas';
import { burn } from 'gpuslider/effects';
import 'gpuslider/style.css';
createSlider(document.querySelector('.gs-stack'), {
  loop: true,
  plugins: [stack(), controls(), canvas({ effects: [burn()] })]
});

Include Video Slides

The canvas handles images and videos. For automatic inline video playback, use muted and playsinline. The videos() plugin starts and stops media as its slide enters or leaves view. This example assumes the video slide is inside the existing .gs-track.

<div class="gs-slide">
  <video class="gs-media" src="demo.mp4" muted playsinline loop preload="none"></video>
</div>
import { createSlider } from 'gpuslider';
import { videos } from 'gpuslider/plugins';
import { canvas } from 'gpuslider/canvas';
import 'gpuslider/style.css';
createSlider(document.querySelector('.gs'), {
  plugins: [videos(), canvas()]
});

Enable a Lightbox

lightbox() opens images when slides are clicked. An image can specify a larger source through data-gs-full, and open(index) also opens the lightbox programmatically.

import { createSlider } from 'gpuslider';
import { canvas } from 'gpuslider/canvas';
import { lightbox } from 'gpuslider/lightbox';
import 'gpuslider/style.css';
import 'gpuslider/lightbox.css';
const slider = createSlider(document.querySelector('.gs'), {
  plugins: [canvas(), lightbox()]
});
slider.plugins.lightbox.open(0);
// Later: slider.plugins.lightbox.close();

React Integration

React projects can import <Slider> and <Slide> from gpuslider/react. The package works with React 18+ and exposes the core slider options and canvas plugins.

import { Slider, Slide } from 'gpuslider/react';
import { controls, stack } from 'gpuslider/plugins';
import { canvas } from 'gpuslider/canvas';
import { liquid } from 'gpuslider/effects';
import 'gpuslider/style.css';
export function Gallery({ photos }) {
  return (
    <Slider
      className="gs-stack"
      loop
      plugins={[controls(), stack(), canvas({ effects: [liquid()] })]}
      aria-label="Photo gallery"
    >
      {photos.map(photo => (
        <Slide key={photo.src}>
          <img className="gs-media" src={photo.src} alt={photo.alt} />
        </Slide>
      ))}
    </Slider>
  );
}

Server Rendering and Plugin Updates

gpuslider/react is a client component entry for Next.js. The server-rendered markup retains native HTML slides. Load the stylesheet during server rendering and reserve slide dimensions with CSS to avoid a layout shift. The plugins prop is read at creation; use remake when a change requires a new plugin configuration.

Core Configuration Options

OptionDefault and behavior
perViewCSS value; number of visible slides, including fractions, or 'auto' for intrinsic widths.
gapCSS value; space between slides in pixels.
axis'x'; use 'y' for a vertical slider.
loopfalse; continuous cycling requires more slides than fit in view, plus one.
align'start'; also accepts 'center' and 'end'.
group1; number of slides advanced per step.
containtrue; avoids empty space at the ends.
freefalse; lets dragging settle between snap positions when enabled.
duration600; slide movement duration in milliseconds.
easeOptional easing function from 0 to 1 over duration, in place of the snapping spring.
start0; initial slide position.
dragtrue; enables pointer dragging.
onOptional object of event listeners, keyed by event name.
plugins[]; plugin instances used by this slider.

Additional Options in gpuslider/full and data-gs

These options enable built-in plugins automatically in the full and declarative entries.

OptionDefault and behavior
mode'row'; 'stack' enables stacked slide transitions.
autoHeightfalse; adjusts slider height to the visible media.
autoplay0; playback interval in milliseconds, or 0 to disable.
keyboardtrue; enables keyboard navigation.
wheeltrue; enables wheel or trackpad navigation.
prevOptional navigation element, collection, or selector.
nextOptional navigation element, collection, or selector.
pauseOptional autoplay pause control element, collection, or selector.
dotsOptional pagination element, collection, or selector.

Built-in Plugins

Core plugins are imported from gpuslider/plugins. Canvas and lightbox use their own entry points. Plugin parameters are included here as part of the configuration reference.

PluginPurpose and parameters
controls({ prev, next, dots })Connects previous/next controls, pagination, and buttons with data-gs-to.
keyboard()Enables Arrow, Home, and End key navigation and a focusable slider.
wheel()Navigates with the mouse wheel or trackpad.
autoplay(3500)Advances on a timer; also accepts { delay, hover, left }. hover: false disables pointer-hover pausing.
marquee({ speed, hover, scroll, turn })Continuous ticker; controls speed, hover slowdown, scrolling response, and reverse direction on upward scrolling. Requires loop: true.
thumbs(other)Uses the slides of another slider as thumbnails.
videos()Manages playback for video slides in view.
autoHeight()Tracks the height of visible slides.
stack()Stacks slides for canvas transitions.
panes({ order, stagger })Transitions individual slide positions. order: 'start', 'end', 'center', or 'random'; stagger: 0 to 1.
progress()Writes slide-progress variables for CSS animations.
loading({ screen, min, timeout, also })Manages media loading and optional loading UI.
quality({ late, frames, steps })Reduces pixel density after slow frames. Defaults: late: 25 ms, frames: 3, and steps: [1, 0.75].
canvas({ effects, eager, density, maxSize, perspective, stage, layer })Adds GPU rendering and shader effects.
lightbox({ punch })Opens slide media in an overlay and optionally carries opening speed into shader effects.

Plugin Methods and Properties

Plugin memberUsage
slider.plugins.autoplay.play()Resumes autoplay.
slider.plugins.autoplay.pause()Pauses autoplay.
slider.plugins.autoplay.pausedCurrent paused status.
slider.plugins.quality.densityCurrent canvas pixel density.
slider.plugins.loading.stateLoading counts and progress.
slider.plugins.loading.doneWhether loading has finished.
slider.plugins.loading.readyPromise resolved when loading finishes.
slider.plugins.lightbox.open(index)Opens a selected image.
slider.plugins.lightbox.close()Closes the lightbox.
slider.plugins.canvas.draw(hook)Registers a canvas drawing hook and returns its cleanup function.
slider.plugins.panes.orderTransition order, writable at runtime.
slider.plugins.hit.at(x, y)Finds the displayed slide at a page coordinate.
slider.plugins.hit.where(index)Gets the displayed position around a slide.

Canvas Configuration

canvas() selects WebGPU or WebGL 2 automatically. Set layer when a project needs a particular backend. The canvas begins loading on user interaction or when an active effect requires it; eager: true initializes it immediately.

OptionDescription
effectsArray of shader effects, applied in the declared order.
eagerInitializes the canvas immediately when true.
densityDevice-pixel density for canvas rendering.
maxSizeMaximum canvas texture size.
perspectivePerspective distance for depth-based effects.
stagePositioned parent element that defines a larger canvas drawing area.
layer'gpu' or 'gl' to select a rendering backend.

Direct Renderer Imports

gpuslider/gpu exports the WebGPU renderer and its effects. gpuslider/gl exports the WebGL 2 renderer and its effects. Explicit renderer imports do not select a second backend when the chosen one is unavailable. For layout effects, hit() keeps clicking aligned with GPU-drawn slide positions.

import { gl, hit, coverflow } from 'gpuslider/gl';
import { createSlider } from 'gpuslider';
import 'gpuslider/style.css';
const effects = [coverflow()];
createSlider(document.querySelector('.gs'), {
  align: 'center',
  plugins: [gl({ effects }), hit({ effects })]
});

Shader Effects

Effects are imported from gpuslider/effects and passed to the canvas plugin. Each function accepts an optional settings object. Only their public parameter names are included below.

EffectBehavior and parameters
stretch({ amount })Stretches media as sliding speed changes.
split({ amount })Separates image color channels during movement.
parallax({ amount, zoom })Offsets media inside its slide.
bend({ amount, speed })Curves the moving slide row.
magnify({ size, strength })Pointer-following magnification lens.
cells({ size, zoom, reach })Pointer-driven magnification grid.
spotlight({ size, dim })Dims the image outside the pointer area.
reveal({ size })Reveals color around the pointer.
glass({ size, lines, amount })Fluted glass distortion near the pointer.
pixels({ size, cells })Enlarged pixels around the pointer.
ascii({ size, cells })Converts media near the pointer into character-like shapes.
tilt({ angle })Tilts a slide toward the pointer.
waves({ size, amount, speed })Animated circular waves near the pointer.
smear({ size, amount })Drags media along pointer movement.
shift({ size, amount })Splits color channels with pointer velocity.
jelly({ amount, across })Elastic slide distortion during movement.
slab({ edge, bend, spread, shine, zoom })Thick glass refraction, bevel, and lighting.
loupe({ size, strength })Lens applied across the entire slider, including the gaps.

Layout Effects

Layout effects change where the GPU draws each slide. Use padding when cards extend outside their original positions. Hit testing follows the displayed image when the canvas manages a layout effect.

Layout effectBehavior and parameters
coverflow({ angle, depth, range })Rotates surrounding slides away from the active one.
pile({ offset, turn })Overlapping cards that move out from the top.
fan({ angle, radius })Fan or circular card arrangement.
wave({ height, length, slope })Moves the row along a wave.
unweave({ amount, threads, start, gap, split, lift })Disperses slides into strips near the edge of the view.
dome({ amount, centre, size })Creates a curved arrangement with smaller edge slides.

Transition Effects

Transitions apply to stack() and panes() layouts. Individual transitions are imported from gpuslider/effects.

  • liquid(), ripple(), glitch(), burn(), pixelate(), swirl().
  • lens(), fluted(), warp(), zoom(), mosaic(), blocks().
  • fold(), signal(), push(), chroma(), kaleido(), displace().
  • datamosh(), wind(), distance(), glyphs(), weave(), lightning().

Transition Helpers

HelperDescription
choose([effectA, effectB])Creates a selectable group of transitions; pick(index) selects a transition for subsequent moves.
sweep(transition)Runs a transition across all visible panes as one continuous image. Use with panes({ stagger: 0 }).
edges(transition, { from, to })Runs an effect where ordinary row slides enter and leave the viewport. from and to are measured in slide widths.
glyphs({ cells, tint })Character-based scramble; cells defines vertical grid rows and tint ranges from 0 to 1.
weave({ threads, tint })Woven transition; threads defines density and tint ranges from 0 to 1.
lightning({ bolts, tint })Electric strike transition; bolts sets strike count and tint ranges from 0 to 1.

CSS Variables and Public Classes

Set --gs-per-view, --gs-gap, and --gs-focus on .gs. The progress() plugin writes per-slide values during motion, and loading() exposes loading-screen state.

CSS variablePurpose
--gs-per-viewNumber of slides in view; fractions are valid.
--gs-gapGap between slides.
--gs-focusMedia focal point, similar to object-position.
--gs-pSigned slide distance from its active position, emitted by progress().
--gs-awayAbsolute slide distance, emitted by progress().
--gs-sharePortion of a slide currently visible, emitted by progress().
--gs-loading-backLoading-screen background.
--gs-loading-colorLoading-screen foreground color.
--gs-loadedLoading progress from 0 to 1.
ClassUsage
.gsSlider root.
.gs-trackContainer holding all slides.
.gs-slideIndividual slide.
.gs-mediaMedia element used for canvas rendering.
.gs-contentHTML content over slide media.
.gs-stackPredefined stacked layout for transitions.
.gs-loadingCustom loading-screen element.
.gs-loadedLoading finished state.
.gs-is-loadingSlider loading state.

Styling Notes

The canvas reads border-radius and corner-shape from the page. Shader effects apply to images and videos, not text, links, or buttons in .gs-content. For axis: 'y', set an explicit slider height. Reduced-motion preferences make slide moves immediate and disable speed-driven and pointer-driven effects.

HTML Data Attributes

The CDN auto initializer uses these declarative attributes. Controls can sit inside a slider or in another element associated with it through data-gs-for.

AttributeFunction
data-gsActivates automatic initialization; accepts a JSON options object.
data-gs-canvasActivates automatic canvas rendering with space-delimited effect names or JSON effect options.
data-gs-gpuRequests the WebGPU renderer with the specified effects.
data-gs-glRequests the WebGL 2 renderer with the specified effects.
data-gs-lightboxActivates a lightbox; also requires lightbox.css.
data-gs-loadingActivates loading UI; also requires loading.css.
data-gs-prevPrevious-slide control.
data-gs-nextNext-slide control.
data-gs-pauseAutoplay pause control.
data-gs-dotsPagination container.
data-gs-toButton that navigates to a specific snap index.
data-gs-forAssociates controls outside the slider with its root element ID.
data-gs-fullLarger image URL for the lightbox.
data-gs-loadedDisplays numeric loading progress in a custom screen.

Dynamic Sliders and Declarative Events

For dynamically inserted declarative sliders, the auto() function initializes new elements and sliders.get(element) retrieves their instances from gpuslider/auto. The gs:ready DOM event bubbles when the slider is initialized and provides the instance in event.detail.

import { auto, sliders } from 'gpuslider/auto';
document.addEventListener('gs:ready', (event) => {
  console.log('Slider ready:', event.detail);
});
auto();
const instance = sliders.get(document.querySelector('.gs'));

Slider API Methods and Properties

createSlider(element, options) returns the instance. Its first parameter is the slider root element and its second parameter is the core configuration object. These methods and properties apply to the returned slider unless marked as plugin-specific.

Method or propertyFunction
next()Moves to the next snap.
prev()Moves to the previous snap.
to(index, { instant })Goes to a snap index; instant skips the animation.
toSlide(index, { instant })Goes to the snap containing a given slide.
count()Returns the number of snap positions.
visible()Returns indexes of visible slides.
set(options)Updates options on the existing slider.
update()Recalculates layout after changes the slider cannot detect.
use(plugin)Registers another plugin on the existing slider.
on(name, fn)Subscribes to an event and returns an unsubscribe function.
once(name, fn)Subscribes once and returns an unsubscribe function.
off(name, fn)Removes an event listener.
emit(name, detail)Emits a custom event with a value.
grab()Begins a programmatic drag.
drag(position)Updates a programmatic drag.
release(velocity)Ends a programmatic drag with velocity.
shift(by, push)Offsets the current and destination positions; push contributes movement speed.
wake()Requests a rendering frame.
layout()Returns measured slider layout for plugins.
destroy()Destroys the instance and restores page markup behavior.
indexCurrent snap index.
previousPrevious snap index.
canNext, canPrevWhether navigation is possible in either direction.
progressPosition through the slides from 0 to 1.
restingIndicates that movement has stopped.
pluginsPlugin instances keyed by their plugin names.
root, track, slidesRoot element, track, and slide elements.
optionsCurrent slider configuration.
motionMotion state for plugins.
viewPer-frame view state for plugins.
winSlider window state for plugins.
signalAbort signal that ends with the slider instance.
slider.on('change', (index, instance) => {
  console.log('Current snap:', index);
});
slider.to(2);
slider.update();

Events

The standard event callback signature is (detail, slider). The wildcard listener receives (eventName, detail, slider). Plugin events fire only when their corresponding features are active.

EventWhen it fires or what it returns
readySlider initialization is complete; detail is the slider.
changeDestination snap changes; detail is the index.
settleSlider comes to rest at a snap; detail is the index.
visibleVisible slide indexes change; detail is the index array.
dragstartDragging starts; detail is motion state.
dragendDrag ends; detail includes release velocity.
clickA slide receives a click; detail is { index, event }.
measureLayout is measured; detail is the layout.
slidesSlides enter or leave the track; detail is the slide collection.
frameA motion frame is drawn; detail is the view.
destroyThe slider is destroyed; detail is the slider.
autoplay:playAutoplay starts or resumes.
autoplay:pauseAutoplay pauses.
autoplay:runSlide timer starts; detail is { delay, left }.
autoplay:waitSlide timer ends early or stops waiting.
marquee:playContinuous ticker starts.
marquee:pauseContinuous ticker pauses.
canvas:readyCanvas selects a backend; 'gpu' or 'gl'.
gpu:onWebGPU canvas takes over drawing.
gpu:offWebGPU returns drawing to page media.
gl:onWebGL canvas takes over drawing.
gl:offWebGL returns drawing to page media.
loading:startMedia loading begins; detail includes total.
loading:progressMedia loading advances; detail includes loaded, failed, total, progress, and media.
loading:doneLoading completes; detail includes loaded, failed, total, time, and late.
lightbox:openLightbox opens; detail is slide index.
lightbox:closeLightbox closes; detail is slide index.
quality:lowerCanvas density decreases; detail is its new pixel density.

React Props and Hooks

The React component exposes the core slider options as props. It also has these component-specific props and hooks.

Prop or hookFunction
loop, align, axis, free, duration, and other core optionsUpdates the live slider when changed.
pluginsPlugins installed when the slider is created.
remakeDependency array that recreates the slider when relevant plugin values change.
indexUpdates the chosen snap when the prop changes.
onChange(index, slider)Called when the snap changes.
onSettle(index, slider)Called when movement settles.
onObject mapping other slider event names to callbacks.
onSliderReceives the slider instance on creation and null on cleanup.
aroundExtra React elements inside the slider beside the slide track.
asElement type for <Slider> or <Slide>, default div.
className, style, id, aria-label, other DOM attributesApplied to the rendered slider element.
useSliderContext()Retrieves slider context inside a <Slider> child.
useSlider(options, dependencies)Hook returning [ref, slider] for custom markup; dependency changes remake the slider.

Loading Plugin Options and State

The loading plugin waits for images and the first frame of each video. Import gpuslider/loading.css for its default screen or use a .gs-loading element of your own. screen: false turns off the overlay but retains progress events. A custom screen present in the initial HTML needs a <noscript> fallback to hide it when scripts are disabled. Failed media count toward completion, and loading() starts images marked loading="lazy" immediately. This behavior suits first-screen galleries and full-page sliders.

OptionDefault and behavior
screenOptional screen element, or false to disable the screen.
min0 milliseconds minimum display time.
timeout10000 milliseconds before completion with late: true; 0 waits indefinitely.
also[]; extra promises to include in loading progress.

Extending gpuslider

Custom plugins are functions that receive a slider instance and return an object. They can register event listeners, modify the measured layout, or request additional animation frames. Plugin registration uses plugins during initialization or slider.use(plugin) later.

Plugin memberPurpose
namePlugin identifier used in slider.plugins.
layout(measured)Runs before the measured layout is used and can modify it.
measure(view)Runs after a layout measurement.
slides()Reacts when the slide collection changes.
frame(view, dt, now)Runs on each animation frame.
busy()Returns true when the plugin needs more frames.
destroy()Cleans up when the slider is destroyed.
Other returned membersExposed by the plugin under its own name.

Plugin View State

A plugin reads view.places[index] for x (pixels), p (relative slide position), share (visible portion), and visible (visibility state).

Custom GPU effects accept params, head, vertex, uv, color, transition, post, place, and animated. The shader hooks have distinct purposes:

Effect hookPurpose
paramsNumeric or 1-to-4-value array uniforms.
headShared GLSL declarations.
vertexvec3(vec3 p, vec2 uv); moves a slide’s mesh in 3D.
uvvec2(vec2 uv); changes texture sampling coordinates.
colorvec4(vec4 color, vec2 uv); changes media color.
transitionGLSL body of vec4 transition(vec2 uv) between stack images.
postvec4(vec4 color, vec2 uv); operates across the composite canvas.
place(p, about)JavaScript hit-test placement corresponding to changed GPU layout.
animatedtrue for autonomous animation or 'pointer' for pointer-driven frames.

Shader Uniforms

The available shader uniforms are uProgress, uVelocity, uPointer, uPointerSpeed, uPointerIn, uTime, uSize, uView, and uQuad. The uv and color hooks can also read uRadius.

Shader Compatibility

The GPU translation supports a restricted GLSL subset. Avoid struct types, GLSL #define, array declarations, out or inout parameters, and partial vector assignments when an effect needs WebGPU rendering. An effect that fails compilation returns the affected slider to HTML media.

Canvas Draw Hook

slider.plugins.canvas.draw(hook) receives (index, quad) before drawing each slide and returns a function that removes the hook. It lets custom code adjust placement, size, visibility, and effects for GPU-drawn slides.

Quad fieldDescription
x, y, w, hDraw position and dimensions in pixels.
pRelative position in slides from the resting position.
radiusCorner radius in pixels.
dimColor multiplier from 0 to 1.
fxEffect intensity from 0 to 1.
speedAdditional motion speed used by shader effects.
clipWhether rendering is clipped to the view.
topDraw priority above other slides.
aImage placement/crop data; null prevents image drawing.

Alternatives & Related Resources

FAQs

Q: Why do remote images appear in HTML but not in the GPU effects?

A: Cross-origin images and videos require CORS response headers and a crossorigin attribute on each media element. A media file that the GPU cannot use as a texture can display through the original HTML element.

Q: Why does the first shader effect appear only after I interact with the slider?

A: The canvas normally initializes when the first interaction or motion requires it. Use canvas({ eager: true }) when the gallery must initialize its GPU canvas immediately.

Q: Can a canvas drawing hook move buttons and links inside a slide?

A: No. draw() changes the GPU rendering position, but interactive HTML stays where the page lays it out. Use a layout effect with a matching place() hook and hit() for accurate slide-level hit testing.

You Might Be Interested In:


Leave a Reply