← All @molecule/* packages · App templates
@molecule/app-image-cropCore interface · image-crop · App (browser) · v1.0.1 · Apache-2.0
Image crop core interface for molecule.dev.
npm install @molecule/app-image-crop@molecule/app-image-crop is the image-crop core interface on the app (browser) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 1 provider: @molecule/app-image-crop-cropperjs.
import { setProvider, requireProvider } from '@molecule/app-image-crop'
import { provider } from '@molecule/app-image-crop-cropperjs'
setProvider(provider) // once, at app startup (bonds.ts)
const cropper = requireProvider().createCropper({
src: '/photos/avatar.jpg',
aspectRatio: 1,
circular: true,
})
const canvas = cropper.getCroppedCanvas({ width: 200, height: 200 })
canvas.toBlob((blob) => uploadAvatar(blob))Providers (1): @molecule/app-image-crop-cropperjs
Works with: @molecule/app-bond
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Image crop core interface for molecule.dev.
Framework-agnostic contract for image cropping: crop-region state
(rect, rotation, zoom) plus cropped-canvas output. Bond a provider (e.g.
@molecule/app-image-crop-cropperjs) to supply the crop math; your UI
renders the preview and drag handles and feeds gestures into the instance.
import { setProvider, requireProvider } from '@molecule/app-image-crop'
import { provider } from '@molecule/app-image-crop-cropperjs'
setProvider(provider) // once, at app startup (bonds.ts)
const cropper = requireProvider().createCropper({
src: '/photos/avatar.jpg',
aspectRatio: 1,
circular: true,
})
const canvas = cropper.getCroppedCanvas({ width: 200, height: 200 })
canvas.toBlob((blob) => uploadAvatar(blob))
core
npm install @molecule/app-image-crop @molecule/app-bond
CropDataCrop region data describing the selected area and transformations.
interface CropData {
/** X coordinate of the crop area origin. */
x: number
/** Y coordinate of the crop area origin. */
y: number
/** Width of the crop area. */
width: number
/** Height of the crop area. */
height: number
/** Rotation angle in degrees. */
rotate: number
/** Horizontal scale factor. */
scaleX: number
/** Vertical scale factor. */
scaleY: number
}
CropperInstanceA live cropper instance returned by the provider.
interface CropperInstance {
/**
* Generates a canvas element containing the cropped image.
*
* @param options - Optional output configuration.
* @returns An HTMLCanvasElement with the cropped result.
*/
getCroppedCanvas(options?: OutputOptions): HTMLCanvasElement
/**
* Returns the current crop region data.
*
* @returns The current crop data.
*/
getCropData(): CropData
/**
* Sets the crop region programmatically.
*
* @param data - The crop data to apply.
*/
setCropData(data: CropData): void
/**
* Resets the cropper to its initial state.
*/
reset(): void
/**
* Rotates the image by the specified degrees.
*
* @param degrees - Rotation angle in degrees (positive = clockwise).
*/
rotate(degrees: number): void
/**
* Zooms the image by the specified ratio.
*
* @param ratio - Zoom ratio (positive to zoom in, negative to zoom out).
*/
zoom(ratio: number): void
/**
* Destroys the cropper instance and cleans up resources.
*/
destroy(): void
}
CropperOptionsConfiguration options for creating an image cropper.
interface CropperOptions {
/** Source image URL or data URI. */
src: string
/** Fixed aspect ratio (width / height). `undefined` for free-form. */
aspectRatio?: number
/** Minimum crop width in pixels. */
minWidth?: number
/** Minimum crop height in pixels. */
minHeight?: number
/** Maximum crop width in pixels. */
maxWidth?: number
/** Maximum crop height in pixels. */
maxHeight?: number
/** Whether the crop area should be circular. Defaults to `false`. */
circular?: boolean
/** Whether to show crop guide lines. Defaults to `true`. */
guides?: boolean
}
ImageCropProviderImage crop provider interface.
All image crop providers must implement this interface to create and manage image cropping UI.
interface ImageCropProvider {
/** Provider name identifier. */
readonly name: string
/**
* Creates a new cropper instance.
*
* @param options - Configuration for the cropper.
* @returns A cropper instance for managing the crop operation.
*/
createCropper(options: CropperOptions): CropperInstance
}
OutputOptionsOutput options for generating the cropped image.
interface OutputOptions {
/** Output width in pixels. */
width?: number
/** Output height in pixels. */
height?: number
/** Fill color for empty areas (e.g. after rotation). Defaults to `'transparent'`. */
fillColor?: string
/** Image quality for lossy formats (0-1). Defaults to `1`. */
quality?: number
}
getProvider()Retrieves the bonded image crop provider, or null if none is bonded.
function getProvider(): ImageCropProvider | null
Returns: The active image crop provider, or null.
hasProvider()Checks whether an image crop provider has been bonded.
function hasProvider(): boolean
Returns: true if an image crop provider is available.
requireProvider()Retrieves the bonded image crop provider, throwing if none is configured.
function requireProvider(): ImageCropProvider
Returns: The active image crop provider.
setProvider(provider)Registers an image crop provider as the active singleton.
function setProvider(provider: ImageCropProvider): void
provider — The image crop provider implementation to bond.| Provider | Package |
|---|---|
| Image Crop | @molecule/app-image-crop-cropperjs |
Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-bond
The instance is headless — no crop UI mounts anywhere. Render the image,
crop-box overlay, and handles yourself (styled via getClassMap()/cm.*) and
translate drag/resize gestures into setCropData() / rotate() / zoom();
read getCropData() to draw the overlay.
Verify the cropped output end-to-end before shipping — draw the returned canvas into the page or upload-and-render it; an empty/blank result means the bonded provider does not implement canvas output, which is an integration bug to fix, not to skip.
Wire with THIS package's setProvider() or bond('image-crop', …) —
setProvider() delegates into the shared @molecule/app-bond registry, so both
write the same slot; requireProvider() throws until one has run.
Upload the result as a Blob (canvas.toBlob) through your upload path; the
server must re-validate the file (type/size) — client cropping is UX, not a
boundary.
Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual crop screen (avatar/photo upload, etc.), and check every box off one by one. A box you can't check is an integration bug to fix — not a skip. The cropper is headless, so verify the UI YOU rendered:
createCropper({ src }))
and renders it with a visible crop-box overlay + drag handles drawn from
getCropData() — not a blank or full-bleed image with no selection.setCropData(),
getCropData() reflects the new x/y/width/height, and the on-page preview
(the getCroppedCanvas() output drawn into the page) updates to show ONLY
the selected area, not the whole image.aspectRatio: 1 for an avatar) the crop
box stays that ratio while you resize — getCropData() width == height for
1:1 — and circular: true clips the preview to a circle.rotate() / zoom() transform the source and the crop overlay follows:
getCropData().rotate / scaleX change and the preview re-renders the
transformed region — the selection isn't stranded on the old orientation.getCroppedCanvas() pixels
match the selected region (not the full source), and downstream the SAVED
file is the cropped Blob (canvas.toBlob → upload) — re-fetch and render the
stored image and confirm it shows the crop, never the original.minWidth/minHeight or larger than maxWidth/maxHeight.