# Cloth Drape

> A hanging fabric banner you can grab, drag and swing: a soft-body cloth simulation that warps your artwork across it and shades its own folds.

Canonical: https://gsapvault.com/effects/cloth-drape
Live demo: https://gsapvault.com/demos/cloth-drape/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | physics, canvas, draggable, momentum, pointer-effects, touch-drag |
| Uses Lenis | No |

## Overview

Real fabric, hanging from grommets, in a canvas element. Grab it anywhere and the sheet deforms locally while the whole thing follows with weight; let go and it swings, ripples and takes its time coming back to rest.

One input drives four visible channels at once: the mesh deforms, your artwork warps with it, the folds shade from their own surface normals, and a soft cast shadow tracks the sheet across the wall behind. Whip it hard and it snaps taut, throws a travelling ripple across the weave and billows toward you.

It is a hand-written soft body on GSAP's ticker: verlet particles, distance constraints, no physics library, no WebGL. Point it at any image with one data attribute.

## Features

- Verlet particle mesh with structural, shear and bend constraints, relaxed several times per fixed step, written from scratch with no physics library
- Grommet pinning: pin as many or as few points along the top edge as you like and the fabric sags into real catenaries between them
- Grabbing takes a patch of fabric, not a single vertex, so a pull makes a fold instead of a spike, and release inherits your pointer's velocity
- Per-vertex lighting from the mesh's own normals, painted as a separate light layer and composited in one pass, so folds shade smoothly with no visible triangle seams
- Your artwork is warped as a real triangle mesh with per-triangle affine mapping, and the triangles are depth-sorted so a fold that doubles over paints in the right order
- Cast shadow rendered from the sheet's live silhouette, so it moves, stretches and softens with the fabric
- Two material presets, silk and canvas, switchable from any button, plus per-instance control of gravity, damping, bend, stretch limit and wind
- Ambient wind keeps the sheet alive at rest without ever reading as jitter, and a gust button or Enter throws a full billow through it
- Fixed 120Hz timestep with an accumulator, so the fabric behaves identically at 60Hz and 144Hz
- Full keyboard path: the sheet is focusable, arrow keys push it and Enter sends a gust

## Use Cases

- Exhibition, festival and gallery sites where the poster itself should be the thing visitors play with
- Fashion and textile brands that want their print shown on something that behaves like fabric
- Hero sections and campaign microsites needing one tactile, memorable interaction above the fold
- Product pages for printed goods: banners, flags, tapestries, scarves, tote prints
- 404 and coming-soon pages where a toy earns the wait

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

The sheet is a grid of verlet particles. Each fixed 1/120s step integrates gravity and a two-wave wind field, then relaxes three sets of distance constraints over several passes: structural links along the weave, shear links across each cell that stop the grid collapsing into a parallelogram, and bend links that skip a neighbour and are what resist creasing. A final pass hard-limits how far any structural link may stretch, which is what makes a hard whip snap taut and sends a ripple travelling across the fabric rather than letting it behave like elastic.

This is a deliberately different physics class from the impulse-based rigid body solver in Physics Word Pile. That effect resolves contacts between separate solid objects with restitution and friction; this one has no contacts at all, and its behaviour comes entirely from relaxing a mesh of constraints toward its rest shape. Both run on GSAP's ticker with a fixed timestep and an accumulator, and neither uses a physics library, but nothing else is shared.

Rendering is a canvas triangle mesh rather than a grid of CSS 3D divs. Three points define an affine transform exactly, so each triangle clips to its own shape and draws the image through that transform, which warps the artwork genuinely; a div grid can only translate and rotate whole cells and shows a seam at every join. Triangles are grown by a fraction of a pixel before clipping so neighbours overlap, and are depth-sorted each frame so a fold that doubles over paints back to front.

Lighting is computed per vertex from face normals averaged across the cells that share it, then painted into a separate opaque light layer and composited over the sheet once with soft-light. Because that layer is opaque, overlapping triangles replace rather than accumulate, which is what stops the mesh printing as a grid; because the light value is linear across a triangle, one linear gradient per triangle reproduces it exactly and the shading comes out smooth rather than faceted.

GSAP drives the wind envelope: a gust is a tween on a single proxy value with a power3.out tail, so it arrives instantly and dies away instead of switching off.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Add to your HTML `<head>`:**

```html
<link rel="stylesheet" href="path/to/style.css">
```

**2. Add before the closing `</body>` tag:**

```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="path/to/script.js"></script>
```

**3. Add the markup to your `<body>`:**

```html
<section class="cd-stage" data-cloth-drape aria-label="Hanging fabric banner">
  <div class="cd-hang">
    <img class="cd-art"
         data-cloth-art
         src="your-artwork.jpg"
         width="1240"
         height="820"
         draggable="false"
         alt="What your banner says">
  </div>
</section>
```

**4. Optional buttons, anywhere on the page:**

```html
<button type="button" data-cloth-gust>Gust</button>
<button type="button" data-cloth-preset="silk" aria-pressed="true">Silk</button>
<button type="button" data-cloth-preset="canvas" aria-pressed="false">Canvas</button>
```

### Options

Set on the `[data-cloth-drape]` container.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-cloth-pins` | Comma-separated fractions `0`–`1` | `0.06,0.5,0.94` | Where along the top edge the fabric is fixed. Fewer pins means deeper sag between them; `0,1` gives a two-corner hang, `0,0.25,0.5,0.75,1` a taut banner |
| `data-cloth-gravity` | Any number (px/s²) | `1700` | Downward acceleration. Low feels like chiffon, high like a wet tarpaulin |
| `data-cloth-damping` | `0.95`–`1` | `0.99` | How much velocity survives each step. Below about `0.97` the fabric stops swinging almost immediately |
| `data-cloth-bend` | `0`–`1` | `0.18` | Stiffness of the links that skip a neighbour, which is what resists creasing. Above about `0.6` the sheet reads as card, not cloth |
| `data-cloth-stretch` | `1`–`1.1` | `1.02` | Hard limit on how far a thread may stretch. This is the taut snap; raise it and the fabric behaves like elastic |
| `data-cloth-wind` | `0` disables | `1` | Multiplier on both the ambient breeze and gusts |
| `data-cloth-shading` | `0`–`1.5` | `1` | Strength of the fold lighting. `0` leaves the artwork completely flat |
| `data-cloth-shadow` | `true`, `false` | `true` | Whether the cast shadow is drawn |
| `data-cloth-cell` | Any number (px) | `38` (`42` on touch) | Target mesh cell size. Smaller means finer folds and more triangles; this is the performance dial |
| `data-cloth-label` | Any string | see below | Accessible name for the canvas |

#### About `data-cloth-cell`

Everything expensive scales with the triangle count, and the triangle count is
the sheet's area divided by the square of this number. The default puts a
620x410 banner at roughly 370 triangles, which is comfortable everywhere. Halve
the cell size and you quadruple the work for folds most visitors will not
notice. The mesh is clamped to 18 cells in each direction whatever you ask for.

#### Presets

`[data-cloth-preset]` buttons apply a whole material at once. Two ship:

| Preset | Feel |
|--------|------|
| `silk` | Light, loose, keeps moving. Deep sag, generous stretch, strong response to wind |
| `canvas` | Heavy and stiff. Barely sags, thuds to a stop, mostly ignores the breeze |

The script sets `aria-pressed` on every preset button and `data-cloth-material`
on the container, so you can style the active state and the fabric together.

### Accessibility

- **Reduced motion**: under `prefers-reduced-motion: reduce` no simulation runs, no canvas is created and no listeners are attached. The artwork stays as a static, fully legible image.
- **No JavaScript**: identical to the above. Nothing is hidden by CSS that only JavaScript reveals.
- **Keyboard**: the canvas is focusable. Arrow keys push the fabric in that direction, which is the keyboard equivalent of a tug; Enter or Space sends a gust. The gust and preset buttons are real `<button>` elements.
- **Focus visible**: the focused canvas takes an inset outline, so it is visible against the artwork rather than lost on the wall behind.
- **Labels**: the canvas gets an accessible name from `data-cloth-label`, and the artwork's own `alt` text stays in the document.

The fabric is a toy, not a reading surface. Put the message in real copy nearby
as well as on the banner.

### Dependencies

**Required:**
- GSAP 3.12+ (core only — no plugins)

**Optional:**
- None

## 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. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Cloth Drape](https://gsapvault.com/effects/cloth-drape)
- [Effects & Templates Vault (£39 one-time, best value): every current and future effect and template](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Image Clip Reveal](https://gsapvault.com/effects/image-clip-reveal.md): A cinematic image reveal where a directional polygon aperture opens as the photograph settles from a restrained Ken Burns scale and its editorial caption lands.

---

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