Hover✨ Premium

Cloth Simulation

A canvas of 20×15 nodes linked by distance constraints simulates a soft textile: top-row nodes are pinned, the rest fall under gravity and react to the cursor within a 50 px radius. Sharp on Retina screens, loop paused off-screen, static cloth under reduced motion.

CanvasClothInteractive

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →

3 usage examples

Reveal curtain on a coming-soon page — the cloth covers the hero title, the visitor moves it to read it — Cloth Simulation example 1

① Reveal curtain on a coming-soon page — the cloth covers the hero title, the visitor moves it to read it

WhenThe visitor lands on a waiting page; the cloth fills the whole background and blurs the overlaid title. By moving the mouse, they wave the cloth and progressively reveal the message.
WhyAn interactive curtain turns waiting into a discovery moment; the visitor actively engages with the page before even reading the content.
SettingsRoot at position:absolute;inset:0;z-index:2;background:transparent — the canvas clearRect lets text below show through; the title (z-index:1) remains readable through the 15 px mesh.
Interactive banner in an organisation header — the cloth replaces a static header image — Cloth Simulation example 2

② Interactive banner in an organisation header — the cloth replaces a static header image

WhenThe foundation banner ripples gently under the navigation bar; the visitor can deform the cloth with their mouse before reading the organisation's mission and statistics.
WhyA live cloth banner at the top of the page replaces a static, heavy hero image; it evokes movement and life without loading a large file.
Settings150 px tall container with overflow:hidden — the canvas (H=300) is clipped to show only the top rows of the cloth; background #0c0c28 (deep indigo) to anchor the cloth in the foundation's blue brand palette.
Interactive product visual in a textile e-commerce sheet — the cloth replaces the static product photo — Cloth Simulation example 3

③ Interactive product visual in a textile e-commerce sheet — the cloth replaces the static product photo

WhenThe visitor hovers over the product preview zone; the cloth deforms under their cursor, conveying a sense of texture and softness that partially replaces the tactile experience.
WhyOn a home-linen or textile product page, virtually manipulating the fabric is more evocative than a fixed photo; it differentiates the interface and increases time spent on the page.
Settings220×220 px container with overflow:hidden and background #100608 (dark burgundy); indigo threads on dark burgundy evoke a dark jacquard textile; canvas.height kept at 300 px for physics.

How it works

The .fx-0388-root wrapper contains a .fx-0388-canvas that is 100 % wide by 300 px tall. At init, the script measures the canvas width, applies devicePixelRatio for the internal resolution, and builds a 15 × 20 = 300-node grid with nodes spaced 15 px apart. The 20 top-row nodes are pinned (pinned: true); the 280 others are free.

Each frame, for each free node: gravity adds 0.2 px/frame downward, the cursor (or finger) within a 50 px radius adds an attraction force proportional to the gap, and elasticity pulls each node back toward its rest position. Velocities are damped by 0.98 per frame. Everything is scaled by dt / 16.67 (elapsed time capped at 50 ms) so the simulation stays stable after a background tab.

An IntersectionObserver watches the root: the loop stops off-screen. Under reduced motion, nodes are drawn in a static grid with no loop. mousemove and touchmove events position the cursor in CSS coordinates (the canvas being in CSS pixels thanks to ctx.scale(dpr, dpr)).

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the loop does not start and the cloth is drawn as a static grid at its initial positions. The effect is visible and readable.
  • Touch: touch-action: none on the canvas prevents page scrolling when a finger slides over it. The effect responds to touch on mobile. If the canvas fills the full width of a mobile page, consider touch-action: pan-y to preserve vertical scrolling.
  • Decorative role: the canvas carries no text or ARIA role. If the cloth represents a product or a flag, expose the name as text nearby.
  • Keyboard: no keyboard interaction is built in — the effect is designed for mouse and touch.

Browser compatibility

Canvas 2D (devicePixelRatio, IntersectionObserver, ResizeObserver, matchMedia), no dependency. IntersectionObserver available since Chrome 51, Firefox 55 and Safari 12.1; ResizeObserver since Chrome 64, Firefox 69 and Safari 13.1. Not measured in Firefox and WebKit.

Chrome 64+✓ Full (measured)
Firefox 69+✓ Full (not measured)
Safari 13.1+✓ Full (not measured)
Edge 79+✓ Full (Chromium engine)
Mobile iOS 13.4+✓ Full (not measured)
Android Chrome 64+✓ Full (measured on Chromium)

Without JavaScript, the canvas stays empty. Without ResizeObserver, the canvas size does not adjust if the frame changes width. Without IntersectionObserver, the loop runs off-screen too.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0388-root"><div class="physics-container"><canvas class="fx-0388-canvas"></canvas><span class="info-label">Help text</span></div></div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Thread colour (JS — ctx.strokeStyle = 'rgba(99,102,241,0.5)') rgba(99,102,241,0.5) (semi-transparent indigo) Replace with your textile colour. An alpha between 0.3 and 0.7 gives the grid transparency.
Gravity (JS — n.vy += 0.2 * scale) 0.2 px/frame 0.05 gives an almost weightless cloth (space-like veil), 0.5 a heavy cloth that falls quickly.
Cursor reaction radius (JS — Math.sqrt(dx*dx+dy*dy) < 50) 50 px 80 px for a broader, softer effect; 25 px for a more pinpoint reaction.
Elastic restoring force (JS — n.vx += 0.01 * (n.ox - n.x) * scale) 0.01 0.03 pulls the cloth back to rest faster (less persistent deformation).
Grid resolution (JS — COLS = 20, ROWS = 15, SEG = 15) 20×15 nodes spaced 15 px apart Increase COLS and ROWS for a finer mesh (more CPU-intensive). Reduce SEG to tighten the nodes.

FAQ

Yes, gradually. The term n.vx += 0.01 * (n.ox - n.x) pulls each node back toward its rest position. Damping (vx *= 0.98) slows the oscillations. Increase the restoring coefficient for a faster return.
Not in this version. Distance constraints keep each segment at its reference length. To simulate tearing, you would remove constraints that exceed a maximum tension threshold.
The canvas is cleared each frame with ctx.clearRect(0, 0, W, H). For a coloured background, add ctx.fillStyle = '#your-colour'; ctx.fillRect(0, 0, W, H); just before drawing the threads, and set the CSS background of .fx-0388-root to the same colour.