# Product Configurator

> An interactive 3D speaker with tactile rotation, three cabinet finishes, a removable grille and guided views of its controls, drivers and connections.

Canonical: https://gsapvault.com/effects/product-configurator
Live demo: https://gsapvault.com/demos/product-configurator/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | webgl-shader, drag, momentum, 3d-transforms |
| Uses Lenis | No |

## Lighthouse, as measured

Google Lighthouse on the demo, 15 September 2026. A measurement of the demo as shipped, not a promise for your page.

| Category | Score |
|----------|-------|
| Accessibility | 100 |
| Best practices | 100 |

No performance score is published: it depends on the deployment (server compression, caching, CDN, connection and device) rather than on the code, so measure it where it will live.

## Overview

A product viewer that lets visitors inspect the things a photograph cannot show. Drag the speaker through a full rotation, compare oak, black and aluminium without losing your angle, or lift its grille to reveal the driver assembly.

Feature buttons compose the object around its top controls, exposed drivers and rear connections. Touch, keyboard and reduced-motion controls remain useful throughout. The included speaker is a procedural three.js demonstration model with an isolated model adapter for your own geometry.

## Features

- Precise drag rotation with momentum, bounded vertical tilt and interruptible settling
- Oak, soft black and brushed aluminium cabinet finishes preserve the exact viewing angle
- A removable grille travels with the speaker as one inspectable assembly
- Guided Controls, Drivers and Connections views pair real geometry with short explanations
- Touch swipes, arrow-key rotation, native buttons and instant reduced-motion states
- Demand rendering stops GPU work at rest and while the viewer is off screen
- Self-contained procedural speaker geometry and textures, plus a real rendered fallback poster
- Independent instance API, replaceable model adapter and complete teardown

## Use Cases

- Audio product pages that need to show construction and rear connections
- Furniture and homeware viewers with material comparisons
- Hardware launches with removable covers and guided feature views
- Product design portfolios presenting multiple finishes of one object

## 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

three.js supplies the model, materials and lighting. GSAP animates the finish changes, rotation settling, removable grille and guided views. The included speaker demonstrates the interaction contract; its construction is separate from the viewer so a developer can adapt the experience to another product.

## 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

Copy `index.html`, `assets/style.css`, `assets/script.js` and `assets/img/speaker-poster.webp` into your project. Open through a web server; ES modules need HTTP(S).

**In the document head**, retain the synchronous WebGL probe and eight-second fallback timeout from `index.html`, load the stylesheet, and include this import map before any three.js import:

_Code snippet omitted: it ships with the download._

**At the end of the body**, load GSAP and the three.js module bridge:

_Code snippet omitted: it ships with the download._

Use the complete error-handling bridge from `index.html` in production. It reveals the poster when a required module fails. The script automatically mounts every connected `[data-configurator]` root. The included markup supplies all controls, their labels and accessible defaults.

Already using three.js? Reuse the host's three.js namespace and `RoomEnvironment` constructor instead of importing a second copy. Assign them before loading the classic effect script. Keep the core and addon versions aligned.

### Using It With Your Own Design

**Markup contract.** A `[data-configurator]` root contains one `[data-viewer]`. Keep the viewer keyboard-focusable with an accessible instruction label. Its `[data-fallback]` contains a product poster and useful description. The optional controls are `[data-finish-option="name"]`, `[data-grille-toggle]`, `[data-feature="name"]` and `[data-reset]`. Use native buttons; `aria-pressed` communicates selection. `[data-finish-label]`, `[data-grille-label]`, `[data-feature-title]`, `[data-feature-copy]` and `[data-status]` receive text updates. Control hooks are scoped to their own instance.

**Styling you can replace.** The product wordmark, typography, panel layout, swatch appearance and neutral palette are demonstration styling. They can all change without changing the viewer. The buttons do not need the supplied visual classes.

**CSS that matters.** Give the root and viewer explicit, nonzero dimensions. Keep the viewer positioned, its canvas filling the viewer, `touch-action: pan-y` for horizontal swipes with page scrolling, and the root's clipping. Keep the fallback visible by default, hidden under `.gl .fallback` or `.is-live .fallback` only. The synchronous probe prevents a poster-to-canvas flash; the timeout restores the poster if loading stalls. Retain visible keyboard focus. The demo's `data-vault-badge-pad` is only needed in Vault previews.

**Your product geometry.** The `createSpeaker(THREE, markDirty)` factory is isolated at the start of `assets/script.js`. Replace it or pass a `createModel` adapter to `mount()`. This requires three.js development; there is no automatic model-file importer. The adapter returns:

- `group`: the `THREE.Group` the viewer rotates and frames. Center your object at its origin and size it to approximately 1.5 × 2.4 × 1.2 scene units, or adapt the viewer's camera/framing values.
- `setFinish(name, duration)`: update the object's materials, calling `markDirty()` as they change. A duration of zero must apply the final state immediately.
- `setGrille(open, duration)`: articulate a removable part in the group's local space. It therefore follows subsequent object rotation. This hook can represent another removable cover.
- `dispose()`: release all geometries, materials and textures owned by the adapter.

`options.finishes` supplies name-keyed records with a `name` label. The model owns what each finish actually changes. `options.features` supplies name-keyed `{ title, copy, x, y, open }` records; `x`/`y` are rotation angles in radians and `open` selects the removable-part state. Adapt the finish buttons and feature hooks to those names. Keep example feature claims accurate for the product you display.

### Options

| Attribute on the root | Default | Description |
|---|---|---|
| `data-finish` | `oak` | Initial finish: `oak`, `black`, `aluminium`, or a name from custom finishes. |
| `data-grille` | `closed` | `open` begins with the grille removed. |
| `data-feature` | none | Optional initial named feature. Its pose and grille state override the neutral view. |
| `data-rotation-speed` | `1` | Drag sensitivity multiplier. `0` disables drag rotation; buttons and keyboard remain active. |
| `data-pixel-ratio` | `2` fine / `1.5` coarse | Rendering resolution cap, clamped to `0.5–2` and the device's actual pixel ratio. |
| `data-capture` | `false` | `true` preserves the drawing buffer for a frozen capture. Leave off for normal use. |

There is no idle spin, autoplay or autonomous drift. GPU rendering runs only when a visible object has changed.

### Accessibility

Native finish, feature, grille and reset buttons support keyboard activation and expose their pressed state. Tab to the viewer and use Left/Right to rotate, Up/Down to tilt and Home to restore the neutral view. Pointer dragging is direct; release momentum can always be interrupted with another drag. Horizontal touch swipes rotate the same assembly while vertical gestures can scroll the containing page.

Reduced motion retains the real 3D viewer and all its useful controls. Finish, feature and grille choices apply immediately, with no release inertia. Changes to the system preference preserve the current finish, angle, grille state and feature. Arrow-key rotation is immediate in either preference.

Without JavaScript, WebGL2 or a required CDN dependency, a rendered poster of the same speaker remains visible with a short description. Configuration controls remain visibly disabled because this fallback is a static view. Context loss also reveals the poster; restoration resumes the renderer.

### Dependencies

| Dependency | Responsibility |
|---|---|
| GSAP 3.12+ (demo pinned to 3.15.0) | Finish, grille, feature and inertial-settle tweens; responsive media contexts and teardown. No GSAP plugins are required. |
| three.js r180 | Procedural geometry, physically lit materials, WebGL2 rendering and resource disposal. |
| `RoomEnvironment` from matching three.js addons | Neutral studio environment reflections. |
| Mona Sans via Google Fonts | Demo typography only; system sans-serif is the fallback. |

No Lenis, external 3D model, model loader or paid texture library is required. Keep the supplied GSAP and three.js licensing notices when packaging dependencies.

### Browser Support

Use a browser with WebGL2, ES modules, import maps, Pointer Events, ResizeObserver and IntersectionObserver. Unsupported or disabled WebGL receives the poster. Serve through HTTP(S), not a local `file:` URL.

### Performance

The first performance lever is `data-pixel-ratio="1"`, especially for larger embeds. The scene redraws only when input, transitions or resizing changes it; offscreen and background-tab rendering is skipped. Textures are procedural and generated once per mounted scene. The camera is resized from the viewer itself, so a container resize works without a window resize. Check your final model and texture budget on real mobile hardware; the included touch checks use an emulated phone.

### Assets

All speaker geometry, wood grain and grille fabric are created by the included source. `assets/img/speaker-poster.webp` is a captured render of that model, with its source and provenance in `assets/img-src/` and `assets/img-manifest.json`. There are no stock photos or generative image assets. Replace the poster when replacing the model. `thumbnail.html` is a build-only frozen presentation of the same model and controls, not a separate implementation.

## 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 for our code. Bundled third-party assets retain their own licences and attribution requirements. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Product Configurator](https://gsapvault.com/effects/product-configurator)
- [The Vault (£99 one-time, best value): every collection in the Vault library, plus future items added to those collections](https://gsapvault.com/effects)

---

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