image-polygon-cropper
v1.0.0
Published
Reusable React polygon image cropper with zoom, pan, and crop metadata output
Readme
image-polygon-cropper
Reusable React polygon image cropper with zoom, pan, a magnifier loupe, crop metadata, and preview output.
Peer dependencies: react and react-dom ≥ 18
Install
npm install image-polygon-cropperyarn add image-polygon-cropperpnpm add image-polygon-cropperQuick start
import { ImagePolygonCropper } from "image-polygon-cropper";
function Example({ file, objectUrl, onDone, onClose }) {
return (
<ImagePolygonCropper
src={objectUrl}
imageFile={file}
onCrop={({ metadata, previewUrl }) => {
onDone({ metadata, previewUrl });
}}
onCancel={onClose}
labels={{
title: "Crop image",
instructions: "Adjust the points by dragging, or click to add more. Click Apply to confirm.",
apply: "Apply",
clear: "Clear",
close: "Close",
}}
/>
);
}Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| src | string | yes | Image URL / object URL |
| imageFile | File | yes | Source file (EXIF-oriented display) |
| onCrop | (result: CropConfirmResult) => void | yes | Called when the user clicks Apply |
| onCancel | () => void | yes | Called when the modal is closed |
| labels | ImagePolygonCropperLabels | no | i18n / custom UI strings |
| colors | ImagePolygonCropperColors | no | Accent theme colors (see Theming) |
| zoom | { min?: number; max?: number } | no | Zoom limits (default 1–5) |
| portalContainer | Element \| DocumentFragment \| null | no | Portal target (default document.body) |
onCrop result
{
metadata: CropMetadata; // bbox, imageSize, polygon, rotation
previewUrl: string; // JPEG data URL of the cropped preview
}Labels
All label fields are optional. Unset keys fall back to English defaults.
| Key | Type | Purpose |
|-----|------|---------|
| title | string | Modal title |
| instructions | string | Shown in the ? hover tooltip |
| loading | string | Loading state |
| pointsCount | (count: number) => string | Points counter |
| closed | string | Closed-polygon badge |
| undoPoint | string | Undo button |
| clear | string | Clear button |
| apply | string | Apply button |
| zoomIn / zoomOut / resetZoom | string | Zoom controls |
| close | string | Close button aria-label |
Theming
Accent colors (Apply button, crop border, handles, loupe) adapt to the host app.
Resolution order for primary:
colors.primaryprop- CSS variable
--primary(shadcn / Tailwind theme) - Built-in fallback
Canvas and instructions backgrounds are fixed neutral greys (#1a1b1e / #2c2e33) and are not themeable.
Case 1 — Host already defines --primary
No colors prop needed:
<ImagePolygonCropper src={url} imageFile={file} onCrop={onCrop} onCancel={onCancel} />Case 2 — Hex / RGB / HSL
<ImagePolygonCropper
src={url}
imageFile={file}
onCrop={onCrop}
onCancel={onCancel}
colors={{ primary: "#22c55e" }}
/>Case 3 — Tailwind default palette name
colors={{ primary: "red-500" }}
// also: "blue-600", "emerald-500", "sky-400", …Case 4 — Full accent override
colors={{
primary: "#3b82f6", // border, handles, loupe, Apply background
primaryDark: "#1d4ed8", // start handle (optional; auto-darkened if omitted)
primaryForeground: "#ffffff", // Apply text (optional)
}}Supported primary formats: #hex, rgb(), hsl(), Tailwind names (red-500), or HSL channels (88 50% 53%).
Styling
Tailwind host apps (recommended)
Do not import image-polygon-cropper/styles.css into a Tailwind app — a second utilities sheet can override classes like .hidden and break layout.
Instead, scan the published package build in your Tailwind content config so utilities are generated once in the host stylesheet:
// tailwind.config.js / tailwind.config.ts
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/image-polygon-cropper/dist/**/*.{js,cjs}",
],Non-Tailwind host apps
import "image-polygon-cropper/styles.css";The shipped CSS is built with Tailwind preflight and container disabled to reduce global collisions.
Features
- Pre-placed rectangle polygon; drag handles or add more points by clicking
- Magnifier loupe while hovering / dragging a handle
- Zoom (wheel or buttons), pan (Space + drag / middle-click)
- Undo last point, clear, apply
- EXIF-oriented display via
imageFile - i18n-friendly
labels - Themeable accents via
--primaryorcolors
Responsibility split
| Host app provides | Package provides |
|-------------------|------------------|
| Image File / URL | Polygon crop UI |
| Translations via labels | Zoom / pan / loupe / undo / apply |
| Upload / API wiring | Crop metadata + preview URL |
| Where to store the result | Core crop helpers |
