section-009

Spatial Product Range

Included in the VaultGet the Vault

A product-first range selector with generated speaker cutouts, a seamless spatial carousel and complete fallback product cards.

advanced
6 more details
webgl-shaderpointer-dragmomentumsnapkeyboard-navigationresponsive-layout
Spatial Product Range - website section preview

This section reads better at your own screen size than in the frame below:

About this section

A complete ecommerce range selector for launches and collection pages. The worked example presents four sculptural desktop speakers with a clear proposition, large product stage, active name, price, finish, defining feature, model link and navigation arrows together in a compact stage footer.

Read the full section overview

Generated transparent product images form a spatial shelf: one model stays centred and readable while its neighbours recede along a shallow arc. Drag or swipe with momentum, use the visible arrows, or browse with the keyboard. Each selection brings the matching product details into view.

The section preserves normal page scrolling and pauses its rendering while out of view. Every product remains described and linked in a scrollable card layout when JavaScript, Three.js or WebGL is unavailable, and for visitors who prefer reduced motion.

What's included

8 items
  • Complete product-range hierarchy with proposition, stage, price, defining feature, finish and model-specific CTA
  • Four generated speaker cutouts shared by the spatial stage and semantic fallback cards
  • Centred readable product with symmetric neighbours receding on a real perspective arc
  • Pointer drag and touch swipe with projected release momentum and frame-rate-independent spring snap
  • Visible previous and next controls, programmatic selection and ArrowLeft or ArrowRight keyboard control
  • Designed mobile WebGL composition with capped pixel ratio and touch-friendly drag
  • Four-card semantic scroll-snap fallback for no JavaScript, missing dependencies, failed WebGL and reduced motion
  • Root-scoped tokens, container-aware layout, independent instances and complete GPU teardown

Perfect for

4 use cases
  • Consumer electronics range and launch pages
  • Furniture, lighting and homeware collections
  • Coffee equipment and countertop appliance families
  • Footwear or accessories presented as a tight model range

How it works

3 sections

The selected product sits at the front of a curved Three.js display, with neighbouring models visible on either side. Dragging follows the pointer or finger, then settles on a model when released. Arrow buttons and keyboard controls offer the same browsing choices, and repeated input smoothly changes the destination.

The active name, price, finish and product link update together with a restrained GSAP transition. The composition adapts to its available space, and multiple sections can operate independently on one page.

Visitors using reduced motion receive complete product cards with ordinary links. The same fallback remains available if the enhanced display cannot load. Removing a section releases its animation and graphics resources without affecting the host page.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

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

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Included in the Vault

Get the Vault to use this section.

The Vault includes Spatial Product Range, the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Sections are available only in the Vault for now while the collection is small.

Documentation

Quick Start

1. Add the stylesheet and WebGL probe to your <head>:

Code snippet omitted: it ships with the download.

The inline probe is required. It hides the fallback before first paint only when WebGL and normal motion are available. If Three.js, GSAP or the renderer later fails, the section removes html.gl and the complete product-card range returns. This prevents a flash of cards while the module is loading without turning failure into a blank section.

2. Copy the complete section from index.html:

Code snippet omitted: it ships with the download.

The example is tuned for four products. Keep every product's visible fallback article: the script reads those records, and the articles are the actual experience under reduced motion or a missing dependency.

3. Load GSAP, Three.js and the section script before </body>:

Code snippet omitted: it ships with the download.

Three.js is loaded as an ES module because its old UMD build is deprecated. The short shim deliberately puts the module on window before appending the classic section script, which keeps that script usable without a build step. Its error path removes the preflight gate, so a blocked CDN restores the fallback instead of leaving a hidden source list.

Already importing Three in your application? Skip the import map and set window.THREE = THREE before assets/script.js executes.

Using It With Your Own Design

Required markup: one [data-spatial-range] root, one [data-spr-source] wrapper containing two or more [data-spr-model] articles, and the enhanced stage/footer block shown in index.html. The script queries only data-spr-* hooks; presentation classes can change if you update the CSS.

Keep the fallback complete. Each product article needs its own name, price, defining feature, finish and real CTA link in visible HTML. Do not replace it with hidden data or an empty loading message. That card range is how the section still performs its sales task with no JavaScript, no WebGL, a blocked CDN or reduced motion.

CSS the mechanism depends on:

  • .spr-stage needs a real height and position: relative; the renderer sizes itself from this element with a ResizeObserver.
  • Keep touch-action: pan-y on the stage so a horizontal drag can select while normal vertical page scrolling continues.
  • Keep the html.gl preflight gate, .is-live source swap and canvas absolute positioning. Those three rules prevent fallback flash and blank failures.
  • The section owns no global reset. The small body style in index.html is preview furniture and may be deleted.

The first image inside each product article supplies both the fallback photo and the Three.js texture. Use a transparent product cutout, fully visible with space around its edges. data-form selects the presentation height in sprCreateSpeaker(record); it does not generate geometry or recolour the image. All images decode before the stage mounts; a missing image restores the cards.

Make It Yours

The fastest rebrand is entirely at the .spr-range root:

Code snippet omitted: it ships with the download.

Edit the proposition and each article in the HTML. The script treats the article data as the shared source for the canvas and active product footer:

Product attribute Purpose
data-name Active model name and screen-reader announcement
data-price Active price
data-feature One defining reason to choose the model
data-finish Finish label beside the swatch
data-colour Six-digit finish swatch colour
data-form compact, wide, tall or tower presentation size
data-link Active model CTA URL

Keep useful alt text and the complete product copy alongside each image. The stage reuses the decoded image, preserving its alpha and natural ratio.

Options

Set these on [data-spatial-range]:

Attribute Default Description
data-drag 1 0 disables pointer drag while keeping buttons and keys
data-snap-stiffness 112 Spring pull toward the selected product
data-snap-damping 18 Spring damping; lower values overshoot more

Numbers use an explicit parser, so 0 is a valid value rather than falling back to the default. There is deliberately no wheel option: a product section must not intercept page scrolling.

Events and Programmatic Control

Each root dispatches:

Event Detail When
sprready { count } The canvas exists and the first frame has rendered
sprchange { index, model } A different model reaches the active position

Code snippet omitted: it ships with the download.

Use revert(), not kill(). The GSAP context cleanup is where observers, listeners, geometries, materials, textures, the renderer and the WebGL context itself are released. Killing the context skips that work and eventually exhausts the browser's context budget.

Accessibility and Integration

  • The four source articles are ordinary semantic content with real links.
  • Previous/next controls are native buttons with visible focus styles. ArrowLeft and ArrowRight work while focus is anywhere in the section except a form field.
  • The active product is announced through a polite live region after deliberate button, keyboard or completed drag selection.
  • Touch uses Pointer Events and keeps vertical page scrolling through touch-action: pan-y. The section never handles wheel events.
  • Under prefers-reduced-motion: reduce, no renderer is created. The complete product cards remain in a horizontal scroll-snap composition on narrow containers.
  • With no JavaScript, missing GSAP, missing Three.js or failed WebGL, the same cards remain visible. The failure path does not log renderer errors because support is probed before a renderer is constructed.
  • The section uses an h2. Change its level to match the host document outline; styling does not depend on the tag name.
  • Container queries switch the layout from the host width rather than the viewport, so the section can sit inside a narrow CMS column.

Test your actual colour edits for contrast. The supplied palette targets a minimum 4.5:1 for ordinary text and visible focus against both the mineral ground and paper surface.

Browser Support

The enhanced stage requires current WebGL and import-map support. The source cards require neither. Browsers with WebGL disabled get the fallback before Three.js attempts renderer construction, keeping the console clean.

Performance

The stage uses twelve textured planes (three repeated slots per product), with transparent edges sorted by depth, no lights and no post-processing. Slots recycle beyond the visible arc with a smooth edge falloff, avoiding visible jumps at the fourth-to-first boundary. Pixel ratio is capped at 2 on fine pointers and 1.5 on coarse pointers. An IntersectionObserver stops the frame loop off screen, and a ResizeObserver on the section root resizes the stage for host-column and iframe changes.

The first performance lever is pixel ratio: change the fine-pointer cap from 2 to 1.5 in sprBuildRange. Keep textures around 1200 pixels high to limit GPU memory. Do not remove the off-screen loop gate or disposal path.

Dependencies and Credits

Dependency Version Role
Three.js 0.180.0 Renderer, perspective camera and transparent product textures
GSAP core 3.15.0 demo pin; 3.12+ supported matchMedia, scoped lifecycle/teardown and active-detail crossfade

No GSAP plugins, smooth-scroll library, runtime fonts, photography or third- party assets are used. GSAP does not drive the continuous 3D motion: the renderer loop integrates the physical state and draws it each frame.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.

Your cart

Your cart is empty

The Vault £99

The Vault library, plus future additions to the library.