A drop shadow that dims what it covers - #81
Merged
Merged
Conversation
The last of #64. A shadow cast by a region onto whatever is behind it, and the point of it is that it dims rather than paints: a shadow that filled its band with a flat colour would erase the dashboard underneath, which is the opposite of what a shadow is for. Every covered cell keeps its character and its hue and only loses some of its light. app.render(({ ui, theme }) => { ui.ctx.overlay(root => { drawShadow(root, dialogRect); // ... then draw the dialog into the same rect }); }); `dimRect` is the effect on its own, for anyone who wants it without the geometry. A `color` option paints instead, for a shadow falling on empty background where there is nothing to dim. Two bugs the ports found, both worth writing down. The colour encoding has a sentinel. Zero is not black -- it means "the terminal's own colour" -- so the first version mixed towards it and *drained* every cell it touched instead of darkening it. Rust disagreeing with the fixture is what surfaced it; the TypeScript looked plausible on its own. It is `rgb(0, 0, 0)` now, in every port, and the fixture that captured the wrong behaviour was regenerated. The corner was dimmed twice. Splitting the shadow into "the band down the side" and "the band along the bottom" overlaps where they meet, and a cell dimmed twice is visibly darker than the rest -- it reads as a smudge rather than an edge. The shadow is now the moved region minus the original, cut into two rectangles that do not touch. A test counts the shades. Dimming goes towards black rather than towards the theme's background: on a light theme the background *is* the light, so dimming towards it would make the shadow brighter than the page it falls on. Six ports, four fixtures, all additive. Verified: 339 TS tests under bun and node; 90 widget scenes matching the reference in Rust, Go, Python, Zig and C++; 11/11 ctest; the galleries; the site builds. Closes #64 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy
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.
The last of #64. A shadow cast by a region onto whatever is behind it, and the point of it is that it dims rather than paints: a shadow that filled its band with a flat colour would erase the dashboard underneath, which is the opposite of what a shadow is for. Every covered cell keeps its character and its hue and only loses some of its light.
dimRectis the effect on its own, for anyone who wants it without the geometry. Acoloroption paints instead, for a shadow falling on empty background where there is nothing to dim.Two bugs the ports found
The colour encoding has a sentinel. Zero is not black — it means "the terminal's own colour" — so the first version mixed towards it and drained every cell it touched instead of darkening it. Rust disagreeing with the fixture is what surfaced it; the TypeScript looked perfectly plausible on its own. It is
rgb(0, 0, 0)now, in every port, and the fixture that captured the wrong behaviour was regenerated.The corner was dimmed twice. Splitting the shadow into "the band down the side" and "the band along the bottom" overlaps where they meet, and a cell dimmed twice is visibly darker than the rest — it reads as a smudge rather than an edge. The shadow is now the moved region minus the original, cut into two rectangles that do not touch. A test counts the shades.
One decision
Dimming goes towards black rather than towards the theme's background. On a light theme the background is the light, so dimming towards it would make the shadow brighter than the page it falls on.
Verified
bun testandnode --test, typecheck cleannext buildfor the siteSix ports, four fixtures, all additive. Closes #64.
🤖 Generated with Claude Code
https://claude.ai/code/session_017Df2FNu5DhinMV2soRz3cy