Skip to content

GIMP-style resize handles in the GUI#34

Merged
irobinson010 merged 7 commits into
mainfrom
feature/gui-resize-handles
Jul 11, 2026
Merged

GIMP-style resize handles in the GUI#34
irobinson010 merged 7 commits into
mainfrom
feature/gui-resize-handles

Conversation

@irobinson010

Copy link
Copy Markdown
Owner

Summary

Grab-and-stretch sizing on the preview, like GIMP's Scale tool: right edge = width, bottom edge = stretch/squish height, corner = free resize (Shift = keep aspect), live cols × rows readout, double-click to reset height to auto. Images/text re-render on release; video sets its knobs and waits for Render.

Mechanics: the sandboxed preview (opaque origin) reports its art's pixel box via an injected postMessage snippet — including natural dimensions for the video <img>, which browsers CSS-downscale — and the API response now includes the post-scaling art grid (art: {cols, rows}), so drags convert exactly to character cells with no font-metric guessing.

Server enablers (each independently useful):

  • exact/max sizing now applies on the colorize-off path too (was silently ignored)
  • video exact rows: frames pre-resize onto the converter's cell grid (braille 2×4 px, glyph 8×16 px) so the natural rows formula lands exactly on the target — --rows on the CLI, video_rows in the API, a Rows field in the Video tab

Height handles hide when a caption is enabled (caption rows would pollute the pixel→rows math); width dragging stays.

Test plan

  • 196 tests pass — art dims in responses, exact sizing without colorize, video rows via API/core/CLI
  • JS syntax-checked; measurement snippet covers static pre, animation player (#m, skipping the caption pre), and video img
  • CI matrix green

🤖 Generated with Claude Code

Drag the rendered art directly instead of typing numbers: right edge =
width, bottom edge = height stretch/squish, corner = free resize with
Shift for aspect lock; live cols x rows readout; double-click resets
height to auto. The sandboxed preview reports its pixel box via an
injected postMessage snippet (handles the video <img> being CSS-scaled
through its natural size), and the server response now carries the
post-scaling art grid so drags convert exactly to cells.

Server enablers: exact/max sizing is honored on the colorize-off path
(previously silently ignored), and video gains exact rows via cell-grid
frame pre-resize (braille 2x4 / glyph 8x16 px cells make the rows
formula land exactly), wired as --rows on the CLI and video_rows in the
API/GUI. Height handles hide when a caption is stitched into the block
(the pixel math would conflate caption rows with art rows).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@irobinson010
irobinson010 requested a review from krakenhavoc July 10, 2026 00:22
irobinson010 and others added 6 commits July 10, 2026 09:17
- A block-level pre stretches to the full iframe width, so the ring
  spanned the whole preview and every re-render snapped it back; measure
  the pre's CONTENT with a DOM Range instead (widest text line).
- Fast drags lost the handle the moment the cursor crossed the iframe,
  which swallows pointer events: setPointerCapture on the handle keeps
  the drag, iframe pointer-events disabled while dragging, touch-action
  none on handles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The server now reports how many rows the caption occupies within the
rendered block (cap_rows + position; zero for the animation player, whose
caption is a separate element). The resize ring subtracts that strip and
wraps just the art, so vertical drags convert cleanly to art rows again —
the caption stays outside the selection, GIMP-style. Cell math simplified
to displayed-box / grid-count, which also handles the CSS-downscaled
video GIF without natural-size juggling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The caption gets its own ring (round handle, dashed outline) wrapping
  just the caption lines: dragging its corner maps width to the caption
  Size knob as a fraction of art width (snapped to the slider's 0.05
  steps), with a percentage readout; double-click resets to 60%. Shown
  only for scalable styles (block/small/shadow/figlet). Server art dims
  now report cap_lines/cap_gap/cap_style so both rings place exactly.

- Figlet corruption fix: the size ladder measured candidates rendered AT
  the art width, where pyfiglet wraps large fonts and smushes the wrapped
  blocks into each other (letters truncated, fragments of neighbors
  bleeding in - 'I see you' lost its I). Candidates now render unwrapped
  for measurement so a mangled wrap can never be selected; when nothing
  fits on one line, the smallest font wraps cleanly into stacked blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Center/right alignment padded each ROW independently, shearing
  multi-row letterforms apart (short rows of a glyph drifted toward the
  middle while long rows stayed put) - the real culprit behind mangled
  centered captions. The block now shifts as a unit.
- The figlet ladder had big gaps (43 -> 61 -> 135 wide for a short
  phrase), so at common art widths half the Size range picked the same
  font and the caption drag felt dead. Added chunky/banner3/epic/
  larry3d/roman/univers rungs; the sweep now moves through distinct
  sizes across the range.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…drag

The caption ring's discrete font-ladder mapping felt dead between rungs.
Captions now take explicit cols/rows (CaptionOptions.cols/rows, threaded
through static, animation, and video paths): the closest natural
rendering is grid-transformed to the exact size, with a missing dimension
derived from aspect. New Width/Height fields in the Caption panel and
--caption-cols/--caption-rows on the image, colorize, and video commands;
the Auto-size slider applies only when the exact fields are empty.

The caption ring gains E/S/SE handles committing exact chars x rows
continuously (Shift-corner keeps aspect; double-click resets to auto),
now hugs the caption's ink instead of the padded row (server reports ink
width and offset), and shows a cols x rows readout. All caption styles
can free-transform, so the style gate is gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@irobinson010
irobinson010 merged commit f2a6007 into main Jul 11, 2026
6 checks passed
@irobinson010
irobinson010 deleted the feature/gui-resize-handles branch July 11, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant