055

Elastic Photo Mesh

£10 or the whole Vault, £99

Interactive rubberized photo mesh: click, drag, or sweep across any image to stretch and warp the canvas texture with spring-mass physics, elastic tension, and gelatin reverberations.

advanced
7 more details
canvasmesh-distortionspring-physicselasticdrag-interactionvelocity-reactivetouch-gestures

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

About this effect

An interactive rubberized photograph rendered as a dynamic 2D spring-mass lattice on HTML5 canvas, powered by GSAP's core ticker with zero external 3D or WebGL dependencies.

Read the full effect overview

Clicking and dragging anywhere on the image grabs the photo like a sheet of stretchable latex, physically pulling and deforming the texture with tactile elastic tension. On release, stored tension snaps back with a high-frequency twang and damped harmonic wave that reverberates across the entire photo surface. Moving the pointer without dragging leaves a subtle magnetic wake that jiggles the mesh in real time.

Elastic Photo Mesh - GSAP animation effect preview

What's included

9 items
  • Interactive 2D spring-mass lattice: subdivides any image into a high-density triangular mesh with interconnected structural springs
  • Click-and-drag rubber stretch: smooth Gaussian-weighted grab radius lets users pinch, pull, and warp the photograph with tactile physical tension
  • Snappy release twang & reverberation: stored elastic potential energy snaps back on release with damped gelatin oscillations propagating to the image borders
  • Affine triangle texture mapping: pure HTML5 2D Canvas rendering via piecewise affine matrix transformations with zero WebGL overhead
  • Hover magnetic wake: moving the cursor across the photo gently indents and ripples the rubber surface at 60fps
  • Keyboard & click pluck impulses: pressing Space/Enter or tapping emits a localized elastic shockwave that echoes across the surface
  • Preset elasticity modes: switch seamlessly between snappy Rubber, wobbly Jelly, and high-tension Taut presets
  • Fully responsive & touch-enabled: works fluidly across desktop pointer drag and mobile touch gestures with Pointer Events API
  • Zero plugin footprint: runs completely on GSAP core ticker with typed-array memory safety and resting-state sleep optimizations

Perfect for

4 use cases
  • Interactive hero showcases for creative studios, digital agencies, and photographers
  • Playful, tactile product imagery for footwear, apparel, and hardware landing pages
  • Engaging interactive portfolio pieces demanding unforgettable tactile feedback
  • Editorial mastheads, digital magazine covers, and creative campaign centerpieces

How it works

1 section

The source image is subdivided into a 2D grid of vertices connected by structural and anchor springs stored in pre-allocated Float32Array buffers. When the user drags, vertices within the grab radius are displaced with smooth cosine falloff. GSAP's ticker runs an Euler integration loop that computes restoring forces toward resting anchor coordinates and neighbor shear relaxation. The deformed mesh is drawn in a single batched pass using canvas affine matrix transformations (ctx.setTransform) clipped to each triangle. When the mesh velocity drops below an idle threshold, the simulation sleeps to preserve CPU cycles until the next interaction.

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.

Paid effect

Purchase to unlock the code.

Buying Elastic Photo Mesh opens 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. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Add to your HTML :

Code snippet omitted: it ships with the download.

2. Add before the closing tag:

Code snippet omitted: it ships with the download.

No GSAP plugins are needed.

3. Add the markup to your :

Code snippet omitted: it ships with the download.

That is the whole contract: a container carrying data-elastic-mesh with one <img> inside it. The script builds the <canvas> itself, measures the container, and takes over.

Using It With Your Own Design

What the effect needs from your markup. A container with data-elastic-mesh holding one <img>. The container must be positioned (position: relative works) and have a real height (an aspect-ratio on the container is the simplest way), because the script sizes its canvas from the container box. The image is cover-cropped to the container aspect ratio, exactly like object-fit: cover.

What is only the demo. The lookbook layout around the frame (the prompt line, the preset buttons, the caption column, the dark ground, Mona Sans) is demo CSS and can go. The preset buttons are optional: any element with data-mesh-preset-btn="rubber|jelly|taut" switches every mesh on the page, and without them the container simply keeps its data-mesh-preset.

Any same-origin image works. Swap the photo by changing the src; the mesh rebuilds automatically, no other change needed. The image must be same-origin or served with CORS headers.

CSS the effect depends on:

Code snippet omitted: it ships with the download.

Options

Set directly as data attributes on the [data-elastic-mesh] container:

Attribute Values Default Description
data-mesh-cols Number (12 to 40) 24 Horizontal grid subdivision density.
data-mesh-rows Number (8 to 30) 16 Vertical grid subdivision density.
data-mesh-preset 'rubber', 'jelly', 'taut' 'rubber' Elastic physics preset defining stiffness, damping, and grab radius.
data-mesh-strength Number (0.2 to 2.5) 1.0 Multiplier for pull force and pluck impulses.
data-mesh-wireframe 'true', 'false' 'false' Render subtle tension stress lines over the mesh (colour from the --mesh-wire custom property).
data-mesh-idle 'true', 'false' 'true' Idle attract: a small pluck every 4.5 seconds while the pointer is away, so the mesh shows itself before anyone touches it. Retires for good after the first drag.

Presets

The effect includes three physics presets:

  • rubber: Balanced, snappy latex snapback with medium damping.
  • jelly: High jiggle, low damping, prolonged elastic gelatin reverberations.
  • taut: High stiffness, low spread, rapid high-tension snap.

Switch presets dynamically via data-attributes or programmatically via the element's API:

Code snippet omitted: it ships with the download.

Accessibility

  • Reduced Motion: Under prefers-reduced-motion: reduce, the script draws the photo static. All spring loops and grab distortions are disabled.
  • No-JavaScript Fallback: The native <img> remains visible if JavaScript fails or is disabled.
  • Keyboard Navigation: With tabindex="0", the stage is keyboard-focusable. Pressing Space or Enter emits an elastic twang shockwave.
  • Assistive Technology: role="img" and descriptive aria-label convey the artwork to screen readers.

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