Skip to content

feat(image-editor): wire Blur tool — drag a rect to blur a region#41

Merged
lyfuci merged 1 commit intomainfrom
feat/image-editor-blur-region
Apr 24, 2026
Merged

feat(image-editor): wire Blur tool — drag a rect to blur a region#41
lyfuci merged 1 commit intomainfrom
feat/image-editor-blur-region

Conversation

@lyfuci
Copy link
Copy Markdown
Owner

@lyfuci lyfuci commented Apr 24, 2026

Summary

Promotes the Blur tool from stub to functional. Drag a rectangle on the
canvas; the area inside is blurred at render time using the canvas
`filter: blur(Npx)` primitive.

Modeled after the Mosaic tool — same "sample the underlying composite,
draw it back in place" pattern, just with a Gaussian blur instead of
pixelation. Cheap, non-destructive, undoable.

Implementation

  • New `BlurShape` (kind: `'blur'`) with x/y/w/h + radius (default 8 px,
    preview-pixel space). Joins the `Shape` union; round-trips through
    serialize/parse via the existing forwards-compat path.
  • `drawing.ts` gets `drawBlurRegion`: `ctx.filter = blur(r * scale)`,
    then `drawImage(underlying, src, dst)` of the rect onto itself. Scale
    applies to the radius so blur looks consistent across preview and
    export.
  • `render.ts` snapshots the canvas before any mosaic OR blur layer (same
    underlying-canvas-read need).
  • `hit.ts` + `transform.ts`: blur falls into the rect-corner-handle
    case, so move + resize "just work" via the existing pattern.
  • `Canvas.tsx`: tool `'blur'` starts a rect-style drag like mosaic.
  • `OptionsBar`: blur shares the simple-hint variant with mosaic/mask.
  • `ToolsPalette`: new entry next to Mosaic in the Annotation group
    (Aperture icon).
  • `LayersPanel`: `annoLabel.blur` for the layer list.

Removes `blur` from `STUB_TOOLS`.

Branched from `main` (independent).

Test plan

  • Press the Blur palette button — selected, options bar shows the blur hint.
  • Drag a rect on the image — area inside is visibly blurred (default 8 px radius).
  • Switch to V, drag a corner handle on the blur layer — region resizes; blur follows.
  • Click + drag the blur layer — region moves.
  • Cmd+Z undoes; Cmd+Shift+Z redoes.
  • Save .json project, reload — blur layer persists.
  • Export PNG — blur is baked at source resolution (radius scaled).

🤖 Generated with Claude Code

Promotes the Blur tool from stub to functional. Drag a rectangle on the
canvas; the area inside is blurred at render time using the canvas
\`filter: blur(Npx)\` primitive. Modeled after the Mosaic tool — same
"sample the underlying composite, draw it back in place" pattern, just
with a Gaussian blur instead of pixelation.

## Implementation

- New \`BlurShape\` (kind: 'blur') with x/y/w/h + radius (default 8 px,
  preview-pixel space). Joins the \`Shape\` union; round-trips through
  serialize/parse via the existing image-shape forwards-compat path.
- \`drawing.ts\` gets \`drawBlurRegion\`: \`ctx.filter = blur(r * scale)\`,
  then \`drawImage(underlying, src, dst)\` of the rect onto itself. Scale
  applies to the radius so blur looks consistent across preview and
  export.
- \`render.ts\` snapshots the canvas before any mosaic OR blur layer (the
  underlying-canvas read is the same need for both).
- \`hit.ts\` + \`transform.ts\`: blur falls into the rect-corner-handle
  case, so move + resize "just work" via the existing pattern.
- \`Canvas.tsx\`: tool 'blur' starts a rect-style drag like mosaic;
  default radius bakes into the new shape.
- \`OptionsBar\`: blur shares the simple-hint variant with mosaic/mask.
- \`ToolsPalette\`: new entry next to Mosaic in the Annotation group
  (Aperture icon).
- \`LayersPanel\`: \`annoLabel.blur\` for the layer list.

Removes \`blur\` from \`STUB_TOOLS\`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lyfuci lyfuci merged commit 260561d into main Apr 24, 2026
2 checks passed
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