feat(ascii): braille, half-block, edge & path-traced vector modes#13
Open
mixflavor wants to merge 2 commits into
Open
feat(ascii): braille, half-block, edge & path-traced vector modes#13mixflavor wants to merge 2 commits into
mixflavor wants to merge 2 commits into
Conversation
The renderer only did square density-glyph fills. Add a `mode` option with three smoother methods, all returning the same Cell[][] so the existing plain/HTML/ANSI serializers keep working: - braille (⣿): 2×4 dot matrix per cell — 8× resolution, curves read smooth - halfblock (▀): split each cell top/bottom; mono uses ▀▄█, coloured carries the top colour as foreground and the bottom as background (two colours + double vertical detail). Serializers gain background-colour support (HTML `background:`, ANSI `48;2`), with spaces/line-ends resetting cleanly. - edge (╱): Sobel edge detect, then stroke the contour with direction glyphs (─ │ ╱ ╲) and leave flats blank — a hand-drawn outline. Crisp on vector input since the raster is clean, so gradient angles are accurate. mode defaults to 'ramp': the original path is byte-identical (14 existing tests unchanged). Studio's charset picker becomes a Style picker grouped into Density ramp / Smooth; seam-fill applies only to the solid-block tilers. 12 new unit tests pin the sub-cell resolution, two-colour carriers, and edge direction mapping. 204/204 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Where `edge` guesses contours with Sobel on a rasterised mark, this samples the *real* SVG geometry — the studio owns the vector, so it can do better. - ascii.ts: strokeToAscii() rasterises grid-space polylines into connected box-drawing art. Each cell's glyph is chosen by which neighbouring cells the line also passes through, so turns become real corners (rounded ╭╮╯╰ or sharp ┌┐└┘) and diagonals become smooth rounded staircases instead of a field of ╱╲ that never join. Pure + unit-tested (7 cases: horizontal, vertical, rounded vs sharp corner, 4-way ┼ crossing, colour carry, empty). - ascii-stroke-dom.ts: the thin browser membrane. Parses the composed SVG, mounts it offscreen at viewBox size (so getCTM maps element space → grid cleanly), walks each geometry element with getPointAtLength, and breaks the polyline on sub-path hops so we never draw a stray line across a hole. Node-guarded (returns null without a DOM); a smoke test pins that. - Studio: new "Vector → Stroke ╭╮ (path-traced)" style with a Rounded toggle; it bypasses the rasterise path entirely. Seam-fill (.tight) now also applies to vector so box-drawing connectors touch across the stretched preview. 34 unit tests pass; both Svelte components parse clean. Co-Authored-By: Claude Opus 4.8 <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.
ASCII used to fill only with square density glyphs. This adds a
modeoption with smoother fills, all returning the sameCell[][]so the existing plain/HTML/ANSI serializers keep working unchanged — plus a standalone path-traced vector renderer that samples the SVG geometry directly.Modes
ramp(default)braille ⣿halfblock ▀▀▄█; coloured▀carries top as foreground + bottom as background → two colours and double vertical detailedge ╱─ │ ╱ ╲, leave flats blankvector ╭╮Why vector is the crown
edgeguesses contours by running Sobel on a rasterised mark. The studio owns the actual vector, sovectormode samples the path geometry itself and draws the centreline as a connected line: each cell's glyph is chosen by which neighbouring cells the line also passes through (box-drawing connectivity), so turns become real corners and there are no disjoint ╱╲ that never quite join.strokeToAsciiinascii.ts): grid-space polylines → connected box-drawing. Fully unit-tested.ascii-stroke-dom.ts): parse → mount offscreen at viewBox size (sogetCTMmaps element space → grid cleanly) → walk each geometry element → break the polyline on sub-path hops so no stray line crosses a hole. Node-guarded; untested by design (CI build + click-test cover the live geometry).Plumbing
background:, ANSI48;2); spaces and line-ends reset cleanly so half-block's two colours render right..tight) applies to the solid-block tilers and the connected vector strokes; braille dots and sparse edge strokes stay crisp.Tests
ramppath byte-identical — + 12 raster-mode + 7 vector-stroke + 1 DOM node-guard smoke).🤖 Generated with Claude Code