# Doodles

> An AI draws with plain SVG shapes (an `<ellipse>`, a few paths) and a 151-byte filter makes
> them read as pen on paper. The drawing travels as a link that is the file, or as a page that
> draws itself.

This is the markdown version of <https://doodled.dev/>. To draw something and get a link, read
[llms.txt](https://doodled.dev/llms.txt). It is self-contained.

## How the pieces connect

Every piece on the page is the one before it, plus one thing:

1. **a shape becomes a line**: the filter; a circle reads as drawn
2. **a line becomes a subject**: eight to twelve shapes, pairs unequal, one proportion wrong
3. **a scene in order becomes a process**: outline before detail, cause before effect; the order is data
4. **one change makes it an argument**: show what moves, and the drawing says why
5. **arguments on one subject make an explanation**: one sentence, one drawing, one claim per piece
6. **explanations in sequence make a course**: a lesson is an explanation that waits for the viewer's prediction before it resolves

## The whole engine

```svg
<filter id="a">
  <feTurbulence baseFrequency=".02" numOctaves="3" seed="3" result="n"/>
  <feDisplacementMap in="SourceGraphic" in2="n" scale="9"/>
</filter>
```

Applied to a plain `<ellipse>` and two `<circle>`s, that is already a doodle. 151 bytes.

## What each part buys

| stage | cost | effect |
| --- | --- | --- |
| clean shapes | 0 | reads as clip art |
| turbulence + displace | 151 B | already a doodle |
| second high-frequency pass | +118 B | an unsteady hand |
| second seed drawn over, plus grain | +206 B | pen on paper |

Stage one is the whole jump. Everything after it is polish.

## The technique

A doodle is a line problem, not a shape problem. The same geometry reads as clip art with a
clean stroke and as a drawing with a degraded one, so nearly all the work goes into degrading
the line and almost none into getting the subject anatomically right.

Because `seed` on `feTurbulence` varies the line for free, six seeds give six different hands
over identical geometry. Geometry and line vary independently, which is why so little code is
needed.

**The limit.** `feDisplacementMap` moves a line; it cannot thin or thicken one. Stroke width
stays uniform, so there is no pressure taper. The editor gets it from
[perfect-freehand](https://github.com/steveruizok/perfect-freehand), which turns pointer input
into a variable-width outline.

## Style

Colour goes in as flat areas under the ink, offset a few units so the register is visibly off,
the way a two-colour print misses. Author one filled shape per subject following its silhouette;
never run the offset over the linework, which duplicates every stroke and reads as a printing
defect. Lettered work skips it: colour under text is unreadable.

## Elsewhere

- [Self-attention](https://doodled.dev/examples/self-attention.html): a page that draws itself; the source is the technique
- [A neuron](https://doodled.dev/examples/neuron.html): when a neuron fires, drawn the same way
- [The seasons](https://doodled.dev/examples/seasons.html): the tilt, not the distance, drawn the same way
- [The model-holder](https://doodled.dev/lessons/): the course, eight lessons that wait for your answer
- [Canvas](https://doodled.dev/canvas): the editor; a link opens into it
- [llms.txt](https://doodled.dev/llms.txt): how to draw and build a link, for agents

By [Jonas Neves](https://jonasneves.com).
