Quick Start
1. Copy the assets folder into your project. Add the stylesheet and this capability gate to your HTML <head>:
Code snippet omitted: it ships with the download.
The small head script keeps the fallback list from briefly appearing before the animated stage. If a dependency cannot arrive, the list returns automatically. Without JavaScript or WebGL 2, it remains visible from the start.
2. Add your project list to the HTML <body>. Use at least two projects; six or more gives the reel a varied sequence:
Code snippet omitted: it ships with the download.
The supplied demo links open their own large images in a new tab. Replace each href with your case study URL, update its accessible label, and remove target="_blank" if you prefer navigation in the same tab.
3. Add the dependencies and loader before your closing </body> tag:
Code snippet omitted: it ships with the download.
Use script.min.js for the compressed version. Serve the page over HTTP or HTTPS; a file:// page cannot reliably load GPU textures.
Already using three.js in your application? Reuse that module instance, assign it to window.THREE, then load the effect script after GSAP. Merge the mapping into your existing import map before any module executes. Do not load a second three.js build or the retired UMD bundle.
Using It With Your Own Design
The effect reads [data-warp-reel], its [data-warp-source] list and each [data-warp-project]. A project needs a decoded image, a data-title, a [data-warp-caption] and a real link marked [data-warp-link]. The optional count, status and step controls use their documented data hooks. The source image and link remain the same semantic elements in both presentations.
The charcoal palette, Mona Sans, project names, year, corner prompt and button styling are the demo's design. Replace those freely. Keep concise project titles; the mobile caption width allows longer names to wrap. If you retain Mona Sans, copy its Google Fonts link from index.html; otherwise the system fallback works.
Keep the root positioned and clipped while .is-live; its height supplies the stage dimensions. Keep the canvas and source overlay absolutely positioned, the source images hidden only in the live state, and the link's pointer events enabled above the canvas. The html.gl rule is only the brief loading gate, never a substitute for the .is-live state. The source list must retain its normal layout as the default.
Vertical touch dragging uses touch-action: pan-x on the live stage. Use this as a dedicated portfolio section with an intentional height; it consumes vertical gestures inside its own surface. Set data-wheel="0" if the surrounding page should receive wheel scrolling. Controls and dragging remain available. Nothing auto-advances, and device orientation is not requested.
Options
Set these attributes on the [data-warp-reel] root before initialization.
| Attribute | Values | Default | Description |
|---|---|---|---|
data-strength |
0–1.35 |
1 |
Additional surface response during movement. Zero keeps the resting roller shape. |
data-barrel |
0–0.5 |
0.4 |
Resting curvature across the width of the ribbon. |
data-wheel |
0, 1 |
1 |
Whether vertical wheel gestures browse the reel. |
data-pixel-ratio |
0.5–2 |
2 fine pointer, 1.5 coarse pointer |
Maximum rendering resolution multiplier. Lower this first for slower devices. |
Choosing Your Images
Choose photographs with clear edges, architectural lines, folds, repeated objects or contrasting shorelines. These reveal the vertical compression and broad surface bend. Soft skies and uniformly blurred scenes give the deformation little to work with. Place the main subject near the middle and leave space near the lower edge for the title and project link.
The demo includes six local WebP derivatives at 1440 × 1000. Landscape images work well on the desktop, while the phone composition crops more tightly around the centre. Use wider sources for a wider stage or a large display. Use accurate width, height and alt attributes, and keep texture images on the same origin or a host allowing cross-origin access. Avoid strong pre-applied colour grading; the surface already adds subtle shading and a lower caption scrim.
Accessibility
- The animated view uses real project links and previous/next buttons, with visible focus rings.
- Arrow keys change projects immediately. Home and End select the first and last project in the current cycle. The active project is announced through a polite live region.
- Only the current project link enters the tab order in the animated presentation. Browsing changes which project link is available; the control buttons remain reachable.
- Touch dragging is the primary phone interaction. A tap opens a link; a drag does not. Native image dragging is disabled.
- Reduced motion, unavailable WebGL 2, blocked dependencies and disabled JavaScript show a regular list of all projects and links. Reduced motion creates no canvas.
- A lost graphics context reveals the same list; the reel resumes if the browser restores the context.
Browser Support
The animated presentation requires a current browser with WebGL 2, ES modules, import maps, Pointer Events, ResizeObserver and IntersectionObserver. Current Chrome, Edge, Firefox and Safari support these features. The normal portfolio list is the designed fallback when graphics support or user preferences require it.
Performance
Rendering pauses outside the viewport and while the document is hidden. Pixel ratio is capped for phones and every image is reused from the decoded source list. Lower data-pixel-ratio first if a device struggles, then reduce image dimensions. A six-project collection at the supplied image size is a practical starting point. The thumbnail preserves its drawing buffer for a stable capture; the normal live renderer does not.
Dependencies
| Dependency | Role |
|---|---|
| GSAP 3.12+ (demo pins GSAP 3.15.0) | Responsive motion conditions, target easing, frame scheduling and cleanup. No GSAP plugins are required. |
| three.js r180 ES module | WebGL renderer, geometry and shader materials for the photographic surface. |
| Mona Sans | Optional demo typography, loaded with display=swap. |
No Lenis, sensor permissions or paid GSAP plugins are used. All six local WebP photographs are included in this effect’s own assets.
Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.