091

Metal Fold

£7
or the whole Vault, £99
Open in new tab

A sculpted metal sheet that dents under your pointer, bending brushed silver and copper reflections across its folds.

advanced
1 more details
webgl-shader

Released

About this effect

A wide, pleated metal sheet suspended on a charcoal stage. Move across the surface to bend its reflections, then press and drag to deepen a local dent. Bright studio bands travel around the folds as the material settles back into shape.

Read the full effect overview

Silver and copper finishes blend smoothly. The composition turns upright on a phone, where touch drives the same pressure response. GSAP shapes the press and release, blends the finish, and owns responsive cleanup; Three.js renders the mesh and material.

Metal Fold - GSAP animation effect preview

What's included

7 items
  • A displaced metal surface with normals that follow every fold and dent
  • Travelling pointer and touch pressure with a controlled 650ms release
  • Brushed silver and copper finishes with reflected studio-light bands
  • A portrait composition for phones and an optional subtle idle pressure drift
  • Keyboard-operated pressure pulse and native material buttons
  • Static sculpture posters for reduced motion, no JavaScript and unavailable WebGL
  • Documented strength, fold depth, settle duration and pixel-ratio controls

Perfect for

3 use cases
  • Material-led portfolio introductions and product microsites
  • Art direction for jewellery, metalwork and industrial design
  • Interactive editorial artwork with a tactile surface response

How it works

1 section

A Three.js surface responds to a moving pressure field. Its changing shape redirects a procedural studio environment, producing the bright bands and darker folds of brushed metal without an external texture or environment map. GSAP controls the pressure envelope and material transition while the render loop smooths pointer movement.

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

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. 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.

The Vault opens this source and the whole library.

Each product gives you the HTML, CSS and JavaScript source, the full documentation and an AI setup prompt, licensed for unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

One payment, over 300 products, and future additions to the library.

Documentation

Quick Start

1. Copy assets/ into your project and add the stylesheet and pre-paint probe to <head>. The probe keeps the static fallback from flashing before WebGL starts. Keep the timeout so an unavailable dependency restores the poster.

In your downloadThe working code for this step, in index.html.

2. Place the component in your page. A definite height is required. The supplied stylesheet uses the viewport; override .metal-fold to fit a hero or a card.

In your downloadThe working code for this step, in index.html.

3. Add the dependencies before </body>. The import map must precede any import of Three.js. Adjust both asset paths when moving the files.

In your downloadThe working code for this step, in index.html.

Already using Three.js in a bundled project? Assign your imported namespace to window.THREE, load GSAP once, then load the effect script after the markup exists. Do not add a second Three.js copy or a second import map. script.min.js can replace script.js.

Using It With Your Own Design

Required hooks: each independent instance needs a [data-metal-fold] root and a .metal-fold__source fallback. The fallback is an ordinary picture element, not an input texture. [data-fold-press] is an optional native button that gives keyboard users the same pressure gesture. Each [data-fold-material] button chooses silver or copper; keep aria-pressed on these toggle buttons.

Removable demo styling: the typeface, control borders, charcoal page ground, full-viewport sizing, cue icon and control positions are presentation. The surface itself is procedural and needs no photograph, HDRI, external environment map or asset loader. Changing the CSS page colour does not change the renderer's clear colour; update renderer.setClearColor() too if you change the stage ground.

CSS to preserve: a positioned root with a definite height; absolute canvas positioning; clipping on the root; controls above the canvas; touch-action: pan-y; and the .gl / .is-live / .is-fallback visibility gates. The pre-paint probe belongs in <head>. The portrait pose is selected from the root's aspect ratio, not the device model.

The supplied posters are stills of the real shader. If you alter the material or fold profile, render matching replacement posters so the reduced-motion and no-JavaScript result stays coherent.

Options

Set attributes on [data-metal-fold] before initialization.

Attribute Range / values Default Meaning
data-strength 0–1.5 1 Maximum depth of pointer and touch pressure; 0 gives a static shape with finish controls.
data-bend 0.4–1.5 1 Depth of the permanent pleats.
data-ambient 0–0.5 0.16 Subtle travelling pressure after 2.5 seconds without input. Set 0 to disable.
data-ease 0.02–1 0.12 Pointer follow fraction at 60Hz, normalized for the elapsed frame time.
data-settle 0.1–2 0.65 Pressure release duration in seconds.
data-material silver, copper silver Initial metal finish.
data-pixel-ratio 0.5–2 2 fine / 1.5 coarse Render resolution cap; coarse pointers always cap at 1.5.

All numeric options accept an explicit 0 where their range allows it. Inputs outside the listed ranges are clamped.

Accessibility

  • Native buttons provide keyboard access to the pressure pulse and both finishes, with visible focus and announced toggle states.
  • Touch presses and horizontal drags drive the same local pressure as a pointer. Vertical page scrolling remains available through touch-action: pan-y.
  • Reduced motion displays the static sculpture poster and hides motion controls. Changing the preference while mounted disposes the canvas immediately; changing it back creates a fresh scene.
  • No JavaScript, unavailable WebGL 2 or blocked dependencies leave the same descriptive, responsive poster visible. There is no mandatory information inside the canvas.
  • WebGL context loss shows the poster until the browser restores the context.

Browser Support

The animated version requires a current browser with WebGL 2, ES modules and import maps. Current Chrome, Edge, Firefox and Safari support these features. WebGL availability depends on the device and its browser settings; the static poster is always the fallback.

Performance

A single displaced mesh renders in one draw call, with 200×100 subdivisions for a fine pointer or 120×64 for touch. The shader needs no image textures or external lighting maps. Rendering pauses outside the viewport and while the document is hidden.

Lower data-pixel-ratio first if the component is costly on your target device, then reduce mesh subdivisions in createMetalScene. The default caps are 2 for fine pointers and 1.5 for coarse pointers. Headless software rendering is useful for visual checks, but its frame rate is not a physical-phone performance measurement.

Dependencies

Dependency Role
GSAP 3.12+ (demo pinned to GSAP 3.15.0) Press/release envelope, silver/copper blend, shared frame clock, matchMedia and teardown.
Three.js (demo pinned to the import-map URL above) Geometry, GPU shader material, camera and rendering.

No GSAP plugins, Lenis, texture packs or environment-map services are required. Continuous pointer smoothing belongs to the render loop; GSAP does not animate the DOM.

Also in your download: the full source, worked examples, the events and programmatic API, and the class reference.

£7