perf: build a shape mask once per composition, and give Motion its own section - #9
Merged
Merged
Conversation
…n section A layer's mask is a pure function of the shape, its direction, the grid size and the layer's seed; nothing in it moves with the phase. It was recomputed for every cell on every frame, for both layers, and for the radial shapes each cell allocated a corner list and took four square roots. On the default canvas that doubled an animated frame, from 103ms to 220ms with a vignette. The mask is now built once as a keep/drop byte per cell and cached the way the field is, and a masked frame costs what an unmasked one does. The random stream is read in the same cell order as before, so the output is unchanged: 1620 generate() calls across twelve mask and direction pairs, three sizes, three texture pairings, five motions and three phases hash identically against the previous generator. Motion moves out from under Settings into its own section, second in the General tab. It is what the site leads with, so it should be findable as a heading, and it is one of the four controls that drive animation rather than a canvas setting. Second rather than first because size, colors and mask come before how it moves, a still is the default, and the flash warning should not be the first line a new visitor reads. The guide's tab table says where it sits. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
flield | 68fd8e3 | Commit Preview URL Branch Preview URL |
Sep 13 2026, 09:40 PM |
The heading sat directly over a field labelled Motion. The section is the topic and the field is the choice, the way Auto-randomize sits over Reroll every, and the site already calls the thing animated backgrounds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this change?
Two things that came out of today's audit follow-up.
The shape mask is built once per composition instead of once per frame. A layer's mask depends only on the shape, its direction, the grid size, and the layer's seed, so nothing in it changes with the animation phase. It was recomputed for every cell on every frame for both layers, and the radial shapes allocated a corner list and took four square roots per cell. On the default canvas a vignette doubled the frame time. The mask is now a cached keep/drop byte array, in the same shape of cache the flow field already uses, and a masked frame costs what an unmasked one does.
Motion gets its own section in the General tab, headed Animation, second after Settings, instead of being the last field under Settings. The heading is Animation rather than Motion so it does not repeat the field's own label directly beneath it; the field is still called Motion everywhere. It is what the site leads with, and it is one of the four controls that drive animation rather than a canvas setting. It sits second rather than first because size, colors, and mask come before how it moves, a still is the default, and the flash warning should not be the first line a new visitor reads. The guide's tab table now says where it lives.
generator.jsmoves to?v=12on the four pages that load it.Related issue
None.
How was this tested?
generator.jsand this one side by side and hashed both grids from 1,620generate()calls: twelve mask and direction pairs, three sizes, three texture pairings, five motions, three phases. Zero mismatches. Old links and exported SVGs render exactly as before.The before and after columns are on different random compositions, so compare the spread within a column rather than across: before, a vignette cost more than double an unmasked frame; after, every mask costs the same as none.
python3 .github/scripts/checks.py mainpasses, including the generator.js bump.Checklist
generator.jsstill has no dependency on the UI, if touched🤖 Generated with Claude Code