Inpaint brushPro
Paint the area an inpainting model should change: brush and eraser with size, feather, invert, undo, redo and clear, pen pressure and touch, and the mask exported as the black and white PNG inpainting APIs expect.
On this page
ProPaint the area to change, describe it and send the mask. The thumbnail is the exported PNG.
Installation
Usage
import { InpaintBrush } from "@/components/ui/chatcn/pro/inpaint-brush"
<InpaintBrush
src={image.url}
alt={image.alt}
width={image.width}
height={image.height}
onMaskChange={(mask) => setMask(mask)}
footer={<PromptRow onSubmit={() => edit(mask.toDataURL())} />}
/>Strokes are stored as vectors in fractions of the image, so the mask is the same at any size: toDataURL() exports it at the image's natural size by default, white where the image should change and black where it is kept, with the feather and invert applied. It encodes only when you call it, so onMaskChange stays cheap. The free image-edit-region marks rectangles and simple brush strokes; this is the full mask editor.
Examples
States
ProEmpty with the hint, inverted, erased, applying, disabled and a broken image.
Props
| Prop | Type | Notes |
|---|---|---|
src, alt | string | The canvas is named "Mask over <alt>" |
width, height, aspectRatio | number | Frame shape before load and the export size |
tool, defaultTool, onToolChange | "brush" | "erase" | Default brush |
size, defaultSize, onSizeChange | number | Brush diameter in px on screen. Default 40 |
feather, defaultFeather, onFeatherChange | number | Soft edge in px on screen, 0 to 48. Default 8 |
invert, defaultInvert, onInvertChange | boolean | Edit everything except the painted area |
defaultStrokes | MaskStroke[] | Reopen an earlier mask |
onMaskChange | ({ empty, coverage, strokes, toDataURL }) => void | After every stroke, undo, redo, clear and invert |
ref | { exportMask, undo, redo, clear, getStrokes } | For your own toolbar or submit flow |
overlayColor, overlayOpacity | string, number | Default the accent token at 0.45 |
submitting, submittingLabel | boolean, string | Locks painting with an "Applying edit" chip |
disabled, toolbar, hint, sizeRange, footer | Lock, hide the toolbar, the empty hint, the size range, a slot below |
Keyboard
| Key | Action |
|---|---|
B, E | Brush, erase |
[, ] | Smaller or larger brush by 4 px; with Shift, by 16 px |
I | Invert the mask |
⌘Z or Ctrl+Z | Undo the last stroke |
⇧⌘Z, Ctrl+Y | Redo |
Delete on the canvas | Clear the mask |
Accessibility
- The canvas is a focusable group with the image's
altand a described hint for the keys. Shortcuts never fire while you type in the footer. - Painting needs a pointer. Keyboard users can invert an empty mask to select the whole image, and every setting is a labeled control.
- Size and feather are sliders that announce their value in pixels; the tools are a toggle group.
- Undo, redo and clear are announced politely.
- Under forced colors the mask paints in the system Highlight color.
Motion
- Painting draws straight onto the canvas with no easing: the mask is exactly where the pointer was. Coalesced pointer events keep fast strokes smooth.
- The brush ring follows the pointer with transforms only. It shows the full size and, inside it, where the feather starts.
- The empty hint and the applying chip fade in 150 ms. Nothing triggered by a key animates.