# Lens Slider Wall

> An infinite wall of sliding photographs that bow through a velocity lens and lift seamlessly into a large viewer.

Canonical: https://gsapvault.com/effects/lens-slider-wall
Live demo: https://gsapvault.com/demos/lens-slider-wall/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | webgl-shader, velocity-reactive, infinite-loop, draggable, click-toggle |
| Uses Lenis | No |

## Overview

A photographic gallery effect that fills the screen with independently sliding image columns. Scroll or drag a column and its photographs curve around an invisible lens; click any image and the same rendered surface unfolds into a large, flat viewer. Five columns on desktop become two on phones, with keyboard navigation and a static image gallery when motion or WebGL is unavailable.

## Features

- Five independent infinite columns on desktop and two on phones, with uninterrupted drift around the active lane
- Velocity lens with bowed edges, centre magnification and a smooth settle
- Continuous mesh transition from the moving wall to a flat image viewer
- Horizontal lightbox slides for previous and next, with an animated return to the wall on close
- Touch drag, wheel momentum and a persistent automatic-motion pause control
- Keyboard browsing by column with arrow keys and visible focus
- Reduced-motion viewer and semantic image-link fallback
- Public controls, resize handling and full GPU cleanup

## Use Cases

- Photography portfolios with an immersive image overview
- Architecture studios with a wall of projects that opens into detail
- Creative archives with independent lanes to explore
- Interior and travel collections with a fluid full-image viewer

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

A three.js mesh is built from each decoded source image. A viewport-anchored vertex field curves and magnifies the photographs according to each column’s velocity, while a time-based GSAP ticker updates continuous motion. GSAP tweens the selected mesh’s vertices from their curved slot into a flat viewing plane and back; it also owns responsive motion preferences and teardown. Native dialog semantics handle the viewer’s focus, Escape key and background inertness.

## Documentation

How this effect works and how it goes into a page. The reference you use once you own the files (worked examples, events, the programmatic API, the class list) ships with the download.

### Quick Start

**1. Copy `assets/` beside your page, then add this to your HTML `<head>`:**

_Code snippet omitted: it ships with the download._

The small synchronous probe prevents the fallback gallery from flashing before WebGL is ready. Its timeout reveals the source if a dependency fails to arrive.

**2. Add the gallery to your HTML `<body>`:**

Copy the `<main data-lens-wall>` block from `index.html`, then replace its twenty source links with your own. Each source item has this shape:

_Code snippet omitted: it ships with the download._

Keep at least five images. The script distributes the source items across five desktop columns or two mobile columns and creates enough mesh instances to fill the stage. The source order is also the viewer’s previous/next order. `data-caption` is optional; the image’s alt text is used when it is absent.

**3. Add this before your closing `</body>` tag:**

_Code snippet omitted: it ships with the download._

Already using three.js? Reuse your existing module import and assign it to `window.THREE` before loading `script.js`. Keep one three.js version on the page. The unminified and minified scripts are equivalent; load one of them. Serve your page over HTTP or HTTPS so module imports and images can load normally.

### Using It With Your Own Design

**Required markup:** one `[data-lens-wall]` stage, a `[data-wall-source]` container containing image links marked `[data-wall-item]`, and the control hooks from the supplied main block. Keep `[data-wall-keys]` empty: the script builds one keyboard control per lane. The native `[data-wall-dialog]` contains the close, previous, next, caption, counter and fallback-image hooks. Use a unique caption ID if mounting several stages in one document.

**Demo styling:** the dark ground, Mona Sans, compact charcoal controls and photographic selection are presentation choices. Replace the palette, typeface, caption styling and toolbar position without changing the data hooks. The twenty example images can all be replaced; their names have no special meaning to the effect.

**CSS that must survive:** the root needs a definite height, `position: relative` and clipped overflow. The canvas fills that root. Keep the `html.gl` and `.is-live` source-visibility rules, the fallback’s scrollable grid, `.is-live` canvas sizing, the native dialog’s transparent WebGL state and its opaque fallback state. `touch-action: none` belongs on the active full-screen wall so vertical touch dragging controls a lane; this is a takeover gallery, so place ordinary page navigation outside it. The keyboard lane controls intentionally use `pointer-events: none` while remaining focusable. Keep the image’s `draggable="false"` and CSS native-drag guard.

The supplied viewer is composed for a stage that fills its viewport, including an iframe viewport. A short embedded component requires adapting the viewer’s DOM positioning and mesh target together.

### Options

Set these attributes on `[data-lens-wall]` before the script starts.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-speed` | Pixels per second, including `0` | `14` | Alternating automatic lane drift continues in the other columns while one is scrolled or dragged. `0` starts paused. |
| `data-strength` | `0`–`1.3` | `1` | Maximum lens intensity. `0` leaves sliding photographs flat. |
| `data-wheel` | `true`, `false`, `all` | `true` | Wheel input moves the lane under the pointer. `all` moves every lane; `false` leaves the wheel to the page. Drag and keyboard browsing still work. |
| `data-duration` | Seconds, including `0` | `0.82` | Viewer opening/closing duration. Interrupted transitions use their remaining distance. |
| `data-caption` | Text | Image alt text | Optional caption on each `[data-wall-item]` link. |

Desktop uses five columns and viewports below 700px use two. These layout choices live in `layout()` and the matching CSS media query. Explicit zero values are preserved for every numerical option.

### Choosing Your Images

The lens rewards visible geometry: architectural edges, layered interiors, a horizon, rows of objects or a clearly framed subject. At speed, those lines bow around the central field. Natural landscapes work too, but a wall containing only fog and featureless sky hides much of the mechanism.

The demo ships twenty WebP photographs at 1600 × 1067. Images are cover-fitted in the wall and contained in the large viewer, preserving their natural colour. Other aspect ratios work; leave space around a subject that must survive the wall’s landscape crop. Meaningful alt text doubles as a useful default viewer caption.

Use local or same-origin images. For cross-origin images, the host must permit CORS and the `<img>` must set `crossorigin="anonymous"` before loading. WebGL cannot upload a photograph the browser treats as an unsafe cross-origin source.

### Accessibility

- **Keyboard:** Tab to a column. Up/Down selects every photograph in that column and centres it immediately; Left/Right moves focus between columns. Enter or Space opens the selected image. Each column button announces the current photograph and its navigation instructions.
- **Viewer:** native `<dialog>` supplies focus containment and makes the background inert. Escape closes, Left/Right browses, and focus returns to the control that opened it. Close and navigation buttons retain visible focus rings.
- **Pause:** the visible Pause control stops automatic drift and existing momentum. Its choice persists through opening and closing the viewer. A visitor can still move a paused wall deliberately.
- **Reduced motion:** the canvas and continuous motion are disabled. A normal, scrollable grid remains, with an instant image viewer and the same previous/next controls.
- **No JavaScript or WebGL:** semantic image links stay usable. With JavaScript but no WebGL, the native viewer still works. Without JavaScript, each link opens its original image.

### Browser Support

The animated version requires WebGL 2, JavaScript modules/import maps, `ResizeObserver` and native `<dialog>`. Current desktop and mobile browsers supporting those APIs run the full wall. The source gallery remains available when WebGL is disabled, texture loading fails or a dependency cannot load. A lost GPU context temporarily restores the source; restoring the context resumes rendering.

### Performance

Reduce photograph dimensions first if GPU memory is tight. Twenty 1600px images are deliberately generous for the large viewer; the script caps texture uploads at 960px wide on coarse pointers while keeping the original source image for the static viewer. Recycled meshes share those textures and one segmented geometry. No postprocessing or blur passes are used.

Canvas pixel ratio is capped at 2 on fine pointers and 1.5 on coarse pointers. Lower those limits in `buildLensWall()` for weaker devices. The ticker stops when the root leaves the viewport, the document is hidden or the WebGL context is lost. Continuous velocities and lens settling use elapsed time with a capped delta, keeping the feel consistent across refresh rates.

### Dependencies

| Dependency | Role |
|------------|------|
| GSAP 3.12+ (demo uses 3.15.0) | Plays the mesh-to-viewer transition, owns motion media queries and cleanup, and supplies the shared ticker. |
| three.js 0.180.0 | WebGL renderer, segmented mesh geometry and image textures. |
| GSAP plugins | None. |
| Lenis | Not used. |

Continuous column travel, momentum and lens decay are calculated in the ticker callback. The vertex shader applies the lens and interpolates the selected mesh into its viewer shape. GSAP animates that interpolation; it does not apply CSS transforms to the photographs.

The bundled control icons are from [Tabler Icons](https://github.com/tabler/tabler-icons), licensed under MIT. Keep `assets/tabler-icons-LICENSE.txt` with redistributed copies. They are inline SVGs and require no icon runtime.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Lens Slider Wall](https://gsapvault.com/effects/lens-slider-wall)
- [The Vault (£99 one-time, best value): everything in the catalogue, including future releases](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Hover Underline](https://gsapvault.com/effects/hover-underline.md): Four material link underlines (an exit-through line, marker sweep, hand-drawn wave, and an endlessly travelling wave) with coordinated type and active-index responses.
- [3D Card Flip Gallery](https://gsapvault.com/effects/3d-card-flip.md): Tactile GSAP 3D cards with deep perspective, reactive edge lighting and shifting shadows. Flip on hover, keyboard focus or tap, with grouped auto-close.
- [Image Clip Reveal](https://gsapvault.com/effects/image-clip-reveal.md): A cinematic image reveal where a directional polygon aperture opens as the photograph settles from a restrained Ken Burns scale and its caption lands.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
