Elastic String Field
A field of fat rubber ribbons that toss themselves in, shove each other apart, and settle into a packed arrangement. Each ribbon is thirty five mass points wired by two spring sets: structural springs between neighbours hold its length, and bending springs between every point and the one two along resist folding, which is what keeps it reading as a stiff band instead of a limp chain. Every point in the field also repels every other point inside the repulsion radius, walls included, so ribbons never overlap and the field distributes itself along its own cushions. A ribbon is born compressed, its points a tenth of a rest length apart along a sine wave, so the springs unpack it into a loop the moment it spawns and it arrives with a toss velocity in a random direction. New ribbons keep dropping wherever there is clearance until the field is full. Press an empty spot to add one, press a ribbon to drag it. Canvas 2D with no physics library.
npx shadcn@latest add https://ui.aryank.space/r/elastic-string-field.jsonInstalls from ui.aryank.space. To add it by hand, copy the files in Usage below, or register the @compronents namespace via the docs.
| Prop | Type | Default | Description |
|---|---|---|---|
| palette / background | string[] / string | eight-colour set / one of them | Ribbon colours. Left unset, background takes a random palette entry and that entry is dropped from the ribbon colours, so the field never paints a ribbon in its own colour. |
| elasticity / bendingResistance | number / number | 0.8 / 0.1 | Spring constants for adjacent points and for points two apart. The second is the ribbon's stiffness. |
| repulsionStrength / repulsionRadius | number / number | 2 / 60 | Push between points inside the radius, which is also the width of the cushion along each wall. |
| damping / gravity | number / number | 0.85 / 0 | Velocity kept per frame, and downward acceleration. Below about 0.8 damping the field never settles. |
| lineWidth / restLength | number / number | 60 / 15 | Stroke weight of a ribbon and the target distance between its points, so together they set how fat and how long it reads. |
| autoSpawn / spawnClearance / spawnInterval / maxStrings | boolean / number / number / number | true / 75 / 100 / 24 | Keep dropping ribbons into any spot that clears every existing point by spawnClearance, waiting spawnInterval between attempts. Every point tests every other point each frame, so maxStrings is the cap that keeps that quadratic honest. |
| initialVelocity | number | 15 | Ceiling on the toss speed a new ribbon is thrown in with. |
lineWidthtextRibbon thickness, 10 to 150.
bendingResistancetextStiffness, 0 to 1. Near zero the ribbons go limp.
repulsionRadiustextSpacing between ribbons and off the walls, 10 to 150.
gravitytextWeightless at 0. Negative floats the field up.
backgroundcolorField colour. Unset, one palette entry is drawn per mount.