PRO

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.

Component
Install
npx shadcn@latest add https://ui.aryank.space/r/elastic-string-field.json

Installs from ui.aryank.space. To add it by hand, copy the files in Usage below, or register the @compronents namespace via the docs.

Files

API
PropTypeDefaultDescription
palette / backgroundstring[] / stringeight-colour set / one of themRibbon 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 / bendingResistancenumber / number0.8 / 0.1Spring constants for adjacent points and for points two apart. The second is the ribbon's stiffness.
repulsionStrength / repulsionRadiusnumber / number2 / 60Push between points inside the radius, which is also the width of the cushion along each wall.
damping / gravitynumber / number0.85 / 0Velocity kept per frame, and downward acceleration. Below about 0.8 damping the field never settles.
lineWidth / restLengthnumber / number60 / 15Stroke 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 / maxStringsboolean / number / number / numbertrue / 75 / 100 / 24Keep 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.
initialVelocitynumber15Ceiling on the toss speed a new ribbon is thrown in with.
Customize
lineWidthtext

Ribbon thickness, 10 to 150.

bendingResistancetext

Stiffness, 0 to 1. Near zero the ribbons go limp.

repulsionRadiustext

Spacing between ribbons and off the walls, 10 to 150.

gravitytext

Weightless at 0. Negative floats the field up.

backgroundcolor

Field colour. Unset, one palette entry is drawn per mount.

Dependencies
None.