One black thread, thousands of straight chords, and a face appears on the loom.
A single thread winds around 240 nails on a circular loom while a greedy solver chooses every move. The target, an eye, a portrait or the moon painted procedurally in code, becomes a map of the darkness each pixel is still owed; from the nail the thread is on, the solver walks the chord to every other nail with Xiaolin Wu anti-aliasing, scores it by the average residual it would cover, takes the best and subtracts the thread's opacity along it. Thread over thread darkens additively, so tone comes purely from how densely chords overlap, and after a couple of thousand chords (over a kilometer of thread at real scale) the picture is unmistakable. The newest chords glow red so you can watch the thread race.
Try it. Paint on the loom to add darkness to the target and steer the thread there (Shift or right drag erases). Scrub the slider or use the left and right arrows to replay the winding, switch subjects and nail counts with the buttons (or 1 to 3 and the up and down arrows), and press T to overlay the target.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a string art generator with JavaScript and the HTML canvas element: one thread wound nail to nail around a circle until a picture appears. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window and stays sharp on high-DPI screens (scale by devicePixelRatio). Draw a cream disc for the board and 200 nails evenly spaced around its edge.
- Make a target image: on a 300 by 300 offscreen canvas, paint something with strong contrast using the canvas API (a big dark circle with a white highlight, or a simple face), then read its pixels into a Float32Array of darkness from 0 (white) to 1 (black). This array is the residual.
- Run a greedy solver. From the current nail, walk the straight line to every other nail (skip the closest dozen), sampling the residual about once per pixel, and score each line by its average residual. Pick the best nail, subtract a small amount (about 0.06) from the residual along that line, and move the thread there.
- Draw each chosen chord on the board as a thin, slightly transparent black line, so overlapping threads build up darkness. Run a few dozen steps per frame and stop when the best score gets very low.
Once that works, make it beautiful:
- Sample lines with anti-aliasing (split each step between the two nearest pixels by their fractional distance) so the solver sees the line the way the canvas draws it.
- Draw a wooden ring and little metal nails with shadows, and highlight the newest chords in red so you can see the thread race.
- Show the line count and the total thread length, and let me paint darkness onto the board to steer the thread.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as loading my own photo, a replay slider through the winding order, or colored threads on a black board.