Skip to content
Sign in
Image studioInpaint brushMenu

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.

ProPaint the area to change, describe it and send the mask. The thumbnail is the exported PNG.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/inpaint-brush

Usage

tsx
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

PropTypeNotes
src, altstringThe canvas is named "Mask over <alt>"
width, height, aspectRationumberFrame shape before load and the export size
tool, defaultTool, onToolChange"brush" | "erase"Default brush
size, defaultSize, onSizeChangenumberBrush diameter in px on screen. Default 40
feather, defaultFeather, onFeatherChangenumberSoft edge in px on screen, 0 to 48. Default 8
invert, defaultInvert, onInvertChangebooleanEdit everything except the painted area
defaultStrokesMaskStroke[]Reopen an earlier mask
onMaskChange({ empty, coverage, strokes, toDataURL }) => voidAfter every stroke, undo, redo, clear and invert
ref{ exportMask, undo, redo, clear, getStrokes }For your own toolbar or submit flow
overlayColor, overlayOpacitystring, numberDefault the accent token at 0.45
submitting, submittingLabelboolean, stringLocks painting with an "Applying edit" chip
disabled, toolbar, hint, sizeRange, footerLock, hide the toolbar, the empty hint, the size range, a slot below

Keyboard

KeyAction
B, EBrush, erase
[, ]Smaller or larger brush by 4 px; with Shift, by 16 px
IInvert the mask
⌘Z or Ctrl+ZUndo the last stroke
⇧⌘Z, Ctrl+YRedo
Delete on the canvasClear the mask

Accessibility

  • The canvas is a focusable group with the image's alt and 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.