UNPKG

@uppy/image-editor

Version:

Image editor and cropping UI

153 lines 5.17 kB
import type { Body, DefinePluginOpts, Meta, UIPluginOptions, Uppy, UppyFile } from '@uppy/core'; import { UIPlugin } from '@uppy/core'; import type { LocaleStrings } from '@uppy/utils'; import Cropper from 'cropperjs'; import locale from './locale.js'; declare module '@uppy/core' { interface PluginTypeRegistry<M extends Meta, B extends Body> { ImageEditor: ImageEditor<M, B>; } } declare global { namespace preact { interface Component { refs: Record<string, any>; } } } type ThumbnailGeneratedCallback<M extends Meta, B extends Body> = (file: UppyFile<M, B>, preview: string) => void; type GenericCallback<M extends Meta, B extends Body> = (file: UppyFile<M, B>) => void; declare module '@uppy/core' { interface UppyEventMap<M extends Meta, B extends Body> { 'thumbnail:request': GenericCallback<M, B>; 'thumbnail:generated': ThumbnailGeneratedCallback<M, B>; 'file-editor:complete': GenericCallback<M, B>; 'file-editor:start': GenericCallback<M, B>; 'file-editor:cancel': GenericCallback<M, B>; } } export interface Opts extends UIPluginOptions { quality?: number; cropperOptions?: Cropper.Options & { croppedCanvasOptions?: Cropper.GetCroppedCanvasOptions; }; actions?: { revert?: boolean; rotate?: boolean; granularRotate?: boolean; flip?: boolean; zoomIn?: boolean; zoomOut?: boolean; cropSquare?: boolean; cropWidescreen?: boolean; cropWidescreenVertical?: boolean; }; locale?: LocaleStrings<typeof locale>; } export type { Opts as ImageEditorOptions }; type PluginState<M extends Meta, B extends Body> = { currentImage: UppyFile<M, B> | null; angle: number; angleGranular: number; isFlippedHorizontally: boolean; aspectRatio: AspectRatio; cropperReady: boolean; }; export type AspectRatio = 'free' | '1:1' | '16:9' | '9:16'; declare const defaultCropperOptions: { viewMode: 0; background: false; autoCropArea: number; responsive: true; minCropBoxWidth: number; minCropBoxHeight: number; croppedCanvasOptions: {}; initialAspectRatio: number; }; declare const defaultActions: { revert: true; rotate: true; granularRotate: true; flip: true; zoomIn: true; zoomOut: true; cropSquare: true; cropWidescreen: true; cropWidescreenVertical: true; }; declare const defaultOptions: { quality: number; actions: { revert: true; rotate: true; granularRotate: true; flip: true; zoomIn: true; zoomOut: true; cropSquare: true; cropWidescreen: true; cropWidescreenVertical: true; }; cropperOptions: { viewMode: 0; background: false; autoCropArea: number; responsive: true; minCropBoxWidth: number; minCropBoxHeight: number; croppedCanvasOptions: {}; initialAspectRatio: number; }; }; type InternalImageEditorOpts = Omit<DefinePluginOpts<Opts, keyof typeof defaultOptions>, 'actions' | 'cropperOptions'> & { actions: DefinePluginOpts<NonNullable<Opts['actions']>, keyof typeof defaultActions>; cropperOptions: DefinePluginOpts<NonNullable<Opts['cropperOptions']>, keyof typeof defaultCropperOptions>; }; export default class ImageEditor<M extends Meta, B extends Body> extends UIPlugin<InternalImageEditorOpts, M, B, PluginState<M, B>> { static VERSION: string; cropper: Cropper | null; objectUrl: string | null; prevCropboxData: Cropper.CropBoxData | null; private imgElement; private cropstartHandler; private cropendHandler; private cropperReadyHandler; constructor(uppy: Uppy<M, B>, opts?: Opts); canEditFile(file: UppyFile<M, B>): boolean; save: () => void; storeCropperInstance: (cropper: Cropper) => void; selectFile: (file: UppyFile<M, B>) => void; resetEditorState: (currentImage?: UppyFile<M, B> | null) => void; rotateBy: (degrees: number) => void; rotateGranular: (granularAngle: number) => void; flipHorizontal: () => void; zoom: (ratio: number) => void; setAspectRatio: (newRatio: AspectRatio) => void; reset: () => void; /** * Start editing a file - creates object URL and prepares state. * Called by hook's start() or when user opens editor. */ start: (file: UppyFile<M, B>) => void; /** * Stop editing - destroys cropper, revokes object URL, cleans up listeners. */ stop: () => void; /** * Initialize cropper on the image element. Called lazily when first edit action is triggered. * For headless use, the hook provides the image element. */ initCropper: (imgElement: HTMLImageElement) => void; /** * Destroy cropper and clean up event listeners. */ destroyCropper: () => void; /** * Get object URL for the current image (used by headless hook). */ getObjectUrl: () => string | null; install(): void; uninstall(): void; render(): import("preact").JSX.Element | null; } //# sourceMappingURL=ImageEditor.d.ts.map