diff options
| author | user <user@clank> | 2026-08-16 16:25:56 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-16 16:25:56 +0200 |
| commit | 2c3297c33678c961e3548d40052808c704c2c85b (patch) | |
| tree | 83b918d81f81c3b2fff58ddd544d87f310135572 /contrib/chrome/README.md | |
| parent | sl0ppty: a race in the reload test, caught at one in eight (diff) | |
| download | slosh-2c3297c33678c961e3548d40052808c704c2c85b.tar.gz slosh-2c3297c33678c961e3548d40052808c704c2c85b.tar.xz slosh-2c3297c33678c961e3548d40052808c704c2c85b.zip | |
sl0ppty: six chrome presets that need the new operators
sine-comet an arc gliding round, with a sine's shoulders
marching-ants two on, two off, stepping -- the selection marquee
standing-wave three lobes that do not travel; the pattern breathes
bit-drift position XOR clock, three bits: a machine thinking
heartbeat lub-dub, then a rest. For a state
xor-barcode the top rule as a barcode, sliding a character at a time
Each is a thing the old language could not say. `sin` and `TAU` give
`sin(TAU * p / perim)` -- this cell's position as an angle round one lap -- which
wraps at the corner for free, because so does a sine, and which fits any whole
number of lobes to the ring exactly. That last property is what makes a standing
wave stand: three lobes and three nodes, in the same places, breathing.
`>> 1 & 1` is a two-cell dash pattern in two operators, with no multiply and no
table; adding a slice of the clock marches it. `^` gives a motif that reshuffles
rather than slides, which is what a machine looks like when it is thinking and
not what any ramp looks like. And `abs(sin())` over a full turn is two humps, so
a heartbeat is one expression and a window mask.
Two techniques worth stealing from these, and now in the README: **overdrive then
clip** (`* 14 - 3000` after a sine keeps only the top of the crest, turning a glow
over everything into an arc), and the **angle idiom** itself.
Every one of them was measured before it was written down -- the perimeter
unrolled into an intensity strip, frame by frame, so an effect that "should"
travel is seen travelling. Two candidates did not survive that: a Sierpinski
`(x & y) == 0`, which on a ring lights the top and left solid and reads as a bug,
and a two-sine interference, which read as noise. `tests/test_chrome_presets.py`
picks up all six with no change, and asserts of each what it asserts of the other
seven: the frame moves, and the pane's own output does not.
Diffstat (limited to 'contrib/chrome/README.md')
| -rw-r--r-- | contrib/chrome/README.md | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/contrib/chrome/README.md b/contrib/chrome/README.md index 12f275f..645d009 100644 --- a/contrib/chrome/README.md +++ b/contrib/chrome/README.md @@ -22,6 +22,12 @@ real session and asserts that the frame moves and the contents do not. | `gradient.kdl` | not animated: lit from the top-left, so the frame reads as a surface | | `corner-glints.kdl` | the four corners breathing together | | `title-sheen.kdl` | the top rule only, where the title sits | +| `sine-comet.kdl` | an arc gliding round with a sine's shoulders, not a ramp's corner | +| `marching-ants.kdl` | two on, two off, stepping round — the selection marquee | +| `standing-wave.kdl` | three lobes that do not travel; the pattern breathes in place | +| `bit-drift.kdl` | position XOR clock, three bits — a machine thinking | +| `heartbeat.kdl` | lub-dub, then a rest. For a state | +| `xor-barcode.kdl` | the top rule as a barcode, sliding a character at a time | ## the perimeter trick @@ -47,6 +53,23 @@ There is no way to name a subexpression, so the formula is written out in full in each file. That is the ugly part of these, and the reason the files are long when the effects are small. +## the angle idiom + +`sin` and `cos` take **degrees**, and `PI` is 180 because pi in an angle language +is a half turn. So `TAU * p / perim` is "this cell's position, as an angle round +one lap", which is the line under most of the newer presets: + +- `sin(TAU * p / perim)` — one cycle over the whole ring, and it wraps at the + corner for free, because so does a sine. +- `sin(TAU * p * 3 / perim)` — three lobes. Any whole number fits the ring + exactly, which is what keeps a standing wave standing. +- `* 14 - 3000` after it keeps only the top of the crest: an arc rather than a + glow over everything. Overdrive then clip is how you sharpen anything here. + +A sine costs a table lookup and no more than the triangle wave +`abs(t / 6 % 510 - 255)` it replaces — but it has no corner in it, which is the +difference between a frame that pulses and one that flickers. + ## two rules worth knowing **`channel="fg"`, always, on a frame.** A border's *background* is the |
