String Art

Portrait of a man in a grey sweater against a pale wall
About this component

String Art

A round board ringed with nails where a single thread is woven pin to pin in real time until a photograph appears, chosen pass by pass by the classic greedy string art method on a grayscale copy of the image. The thread being pulled is highlighted, finished portraits rest, fade and give way to the next photo, hovering speeds the weaving and leans the board, and a click moves on. Pins, passes, thread weight, colors, speed, hold, rim and tilt are props; the work is time sliced so it never blocks the page, and reduced motion weaves the finished portrait without the needle or tilt.

Usage

The import and the props worth knowing about, in one place.

import { StringArt } from "@/components/beste/component/string-art";

<StringArt
  className="aspect-square w-full max-w-[560px]"
  images={[
    { src: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=900&q=80", alt: "Portrait of a man", focus: 0.32 },
  ]}
  pins={240}                   // nails around the board
  lines={3500}                 // most passes per portrait; it stops sooner once the picture is done
  threadColor="var(--foreground)"
  needleColor="var(--primary)" // the pass being pulled right now
  speed={320}                  // passes per second
  hold={6}                     // seconds a finished portrait rests
/>

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
images*StringArtImage[]—Photos woven one after another. Loaded with CORS so the canvas can read them.
pinsnumber—Nails around the board.
linesnumber—Most thread passes per portrait; the weave stops earlier once the picture is used up
threadOpacitynumber—Ink each pass leaves, 0 to 1.
threadColorstring—Thread color. Any CSS color, tokens included.
boardColorstring—Board color.
needleColorstring—Color of the thread being pulled right now.
contrastnumber—How hard the photo is pushed toward black and white before weaving, 0 to 1.
speednumber—Thread passes per second.
holdnumber—Seconds a finished portrait rests before the next one starts.
rimboolean—Thin rim around the board.
tiltnumber—How far the board leans, idle and toward the cursor, 0 to 1.
interactiveboolean—Hovering speeds the weaving and leans the board; a click starts the next portrait.
pausedboolean—Stop weaving where it is.
classNamestring—
childrenReactNode—

More Media components

View all Media
A modern house with wide glass walls and a pool
Snowy peaks under the Milky Way above a dark line of pines