Power-User Systems

Weave

A sheet of cloth on a position-based solver — particles and distance constraints relaxed to convergence every fixed step, with no forces, no rotations and no contacts. Drag it, load it, and pull until the constraints fail and the tear runs. Every quad is shaded by its own extension against the tear threshold, so the load path through the sheet is visible long before anything breaks.

Install

# Weave needs no npm packages

Then copy 2 files into your project:

  • components/registry/weave/weave.tsx
  • hooks/use-animation-loop.ts

Props

PropTypeDefaultDescription
colsnumber26Particles across the sheet. Constraint count grows as roughly twice cols times rows and every one is visited on every relaxation pass, so this and rows together are the honest cost dial.
rowsnumber18Particles down the sheet. Taller than it is wide is what makes the drape read as fabric; a square grid hangs like a banner and never folds.
iterationsnumber6Relaxation passes over the constraint list per fixed step. Position-based dynamics has no exact solve — it converges, and this is how far it gets. One pass is rubber, six is linen, and past ten you are paying for a stiffness you cannot see.
gravitynumber9.8Uniform downward acceleration. Zero leaves the sheet floating so wind alone drives it, which is the clearest way to watch a strain wave cross the mesh.
windnumber4.2Lateral forcing, applied with a travelling phase rather than uniformly — a uniform push only translates the sheet and never ripples it.
stiffnessnumber0.9Fraction of each constraint's length error corrected per pass. One with enough passes is inextensible canvas; low values are jersey that stretches under its own weight. It trades against iterations almost multiplicatively — halving one and doubling the other lands in nearly the same place.
dampingnumber0.02Velocity bled off per step. Verlet carries velocity implicitly in the gap between the current and previous position, so this scales that gap rather than a stored vector — which is why it reads as air resistance and not as friction.
tearThresholdnumber1.9Extension at which a constraint fails, as a multiple of its rest length. Evaluated after all relaxation passes, never during them: strain measured mid-solve is an artefact of the sweep order, and tearing on it produces failures that follow the constraint list rather than the load. Above about four nothing tears at any wind you can set.
pinMode"top-row" | "corners" | "top-and-bottom" | "free""corners"Which particles are held. Corners is the one worth pulling on — the load concentrates into two diagonals you can see in the strain field long before anything tears. Free drops the whole sheet, and is the honest demonstration that none of this is keyframed.
shading"strain" | "wireframe" | "solid""strain"How each quad is filled. Strain shades it by the extension of its own four edges, which is the point of the component: the load path through a hanging sheet is invisible in a wireframe and obvious the moment it is coloured.
tintstring (hex)"#a855f7"The cloth at rest — zero strain. Also the anchors and the ring on a held particle.
strainColorstring (hex)"#f87171"The far end of the strain ramp, reached exactly at the tear threshold — so a quad going fully hot is a prediction rather than a decoration.

What It Demonstrates

Drag
Moving an element by grabbing it, often with momentum when released.
Stiffness / Tension
How strongly the spring pulls toward its target. Higher feels snappier.
Damping
How quickly a spring settles. Lower damping means more bounce and oscillation.
Velocity
How fast and in which direction an element is moving. A spring carries it into the next animation when interrupted, so a flicked element keeps its speed.
Momentum
Motion that carries velocity, especially after a drag or interruption.
Frame rate (FPS)
Frames drawn per second. 60fps is the baseline for smooth motion; 120fps on newer displays.

Related Components

Appears In