Art from equations — drawn live in your browser, ready for a real pen.
Every image in LINEWORK is generated by a few lines of mathematics running in your browser. Nothing is a photo, nothing is pre-rendered. Curves are traced stroke by stroke with plain trigonometry and noise; the moving pieces are GPU shaders. And every plotted piece exports as plotter-ready SVG, so a drawing can leave the screen and become physical ink on physical paper.
→ Live gallery: feynma1h.github.io/linework
No frameworks. No build step. No dependencies. Just ES modules a browser runs as-is.
The site is one argument in five chapters — a deliberate progression, not a menu:
| # | Chapter | What it is |
|---|---|---|
| 01 | The Collection | One equation, one image — the vocabulary |
| 02 | Compositions | Many equations sharing one frame — the chorus |
| 03 | Editions | Layered, signed prints — the finished artifact |
| 04 | In Motion | The same ideas alive on your GPU |
| 05 | Make your own | Your turn — fork it and write a rule in code |
Every piece has sliders, a live "plot-it-in-front-of-you" animation, a lightbox, a shareable permalink that encodes the math itself, and PNG + SVG export.
- Fork this repository (or use it as a template).
- Open
src/config.jsand put your name and fork in:Every "fork this" link and the footer signature follow from that.export const SITE = { artist: 'Your Name', repo: 'https://github.com/you/linework', year: 2026 };
- Turn on GitHub Pages: repo → Settings → Pages → Source → GitHub Actions, then run
Deploy to GitHub Pages from the Actions tab (on a fork, allow workflows there first).
Your gallery gets a public URL in about two minutes, and every push to
mainredeploys it. - Once you know that URL, update the
<head>ofindex.html—canonical,og:urlandog:imageare absolute, so they need to point at your site for link previews to work.
That's the whole deployment. To make new art, see below.
A new artwork is one object in src/art/collection.js:
{
title: "My Curve",
equation: "the math, shown under the picture",
params: [ { key:"n", label:"knob", min:1, max:9, step:1, value:4 } ],
*draw(ctx, w, h, p, rng) {
// ctx is a normal 2-D canvas context (w × h in CSS pixels).
// p.n is the live slider value; rng() gives seeded [0,1).
// `yield` now and then → it plots itself live on screen
// AND becomes a vector path in the SVG export. That's it.
}
}Reload the page — it appears, wired with sliders, shuffle, exports and a lightbox.
No registration step, no build. (Add a GPU piece the same way in
src/art/shaders.js.)
Full details in CONTRIBUTING.md.
Because the site uses native ES modules, browsers won't load it directly off the filesystem — you need to serve it over HTTP (any static server works):
python3 -m http.server 8000
# then open http://localhost:8000or, if you prefer Node:
npx serveindex.html markup only — no logic lives here
og.png the link-preview card (generated, see below)
thumbnail.png 4:3 project thumbnail
styles/linework.css the two themes (paper / blueprint) and layout
tools/
share-card.html redraws og.png from the gallery's own pieces
.github/workflows/
deploy.yml publishes index.html, og.png, src/ and styles/ to Pages
src/
config.js ← your name and site details
main.js entry point: theme, shortcuts, permalinks, boot
core/ the reusable engine
palette.js themes + colour helpers
math.js seeded RNG + value noise
dom.js canvas sizing, toasts, downloads
engine.js render / animate / export a piece
svg.js the recorder that makes everything plotter-ready
art/ the artwork itself — edit these to add pieces
collection.js 01 · single-equation pieces
compositions.js 02 · many-equation frames
editions.js 03 · layered prints
layers.js reusable painters shared by the editions
shaders.js 04 · GPU fragment shaders
registry.js the ordered list the gallery renders
views/ the UI, one file per section
gallery.js lightbox.js hero.js motion.js
The trick that keeps it honest: a single draw() generator per piece drives both
the on-screen animation and the SVG export. There is no second copy of the drawing
code — core/svg.js is a fake canvas context that turns the same
strokes into vector paths.
Even the share card follows that rule. og.png is not artwork someone made in a
design tool — tools/share-card.html runs three of the
gallery's own generators onto a 1200 × 630 plate, so the preview can't drift from
the work it advertises. Open it over HTTP and press save og.png to redraw it.
Every plotted piece exports as SVG with real vector paths.
Feed that file to an AxiDraw or any pen plotter and the
drawing becomes ink on paper, the way string artists and spirograph makers work by
hand. The paper-coloured background sits on its own layer (id="paper") so you can
delete it before plotting on your own stock.
MIT © 2026 Utkarsh Singh. Fork it, remix it, sign it with your own name.