Naughty Program Manipulator


    0.1.16-fabric • Public • Published

    React Multi Cropper

    A component for allowing multiple cropping regions on a single image, powered by fabric.

    build version size downloads

    WIP: Certain aspects are in development, and may be incomplete or buggy.
    It should be fine for most purposes.



    yarn add react-multi-cropper fabric


    yarn install
    yarn start # in one terminal
    yarn serve # in another

    Then open http://localhost:3000 in your browser.
    If 3000 is occupied, the terminal output will show you what URL the serve command is serving on.


    See the examples/index.tsx file.


    Draw rectangular regions on an image to obtain the selected area as a base64 encoded data URL.
    Multiple regions can be obtained by drawing multiple boxes.

    The component is responsive, so the image dimensions can use relative units (like %), and the cropping regions/rectangles should stay in place w.r.t. the image.

    The cropping logic is aware of the device pixel ratio, so you won't get blurry crops on a MacBook or phone.


    Default Usage

    const Cropper = ({ imageUrl }: { imageUrl: string ) => {
      const [boxes, setBoxes] = useState<CropperBox[]>([]);
      const [imageMap, setImageMap] = useState<CropperBoxDataMap>({});
      const updateBoxes = (_, __, _boxes) => setBoxes(_boxes);
      return (
            onCrop={(e, map) => setImageMap(map)}
            onLoad={(map) => setImageMap(map)}
          {, i) =>
            !!imageMap[] && <img src={imageMap[]} key={i} />

    How to reset zoom, rotation, and pan?

    In examples/index.tsx, you'll see an implementation of reset.

    const reset = () => {

    setRotation, and setZoom are simple state setting functions obtained from a useState.
    resetCenter needs a few more lines.
    Note: Due to the current implementation, when resetting the component you must reset rotation before zoom to avoid bugs. It would be changed in the future to use a different update mechanism.

    The second argument of onLoad provides the reset handler. To call this from anywhere, you may want to assign this to a ref.

    // Initialize a ref to store the function
    const resetCenterRef = useRef(() => {});
    const resetCenter = resetCenterRef.current;
    // Call function anywhere
    // Obtain the function from onLoad
    onLoad={(map, reset) => {
      resetCenterRef.current = reset;

    Props for the MultiCrops component

    type CropperProps = {
      cropperRef?: MutableRefObject<fabric.Canvas | null>;
      src: string;
      zoom?: number;
      rotation?: number; // degrees
      cropScale?: number; // the scale of the resultant cropped images
      boxes: CropperBox[];
      onChange?: UpdateFunction;
      onDelete?: UpdateFunction;
      onBoxMouseEnter?: UpdateFunction;
      onBoxMouseLeave?: UpdateFunction;
      onBoxClick?: UpdateFunction;
      onLoad?: ImgOnLoadWithImageData;
      onCrop?: CropTriggerFunctionWithImageData;
      onZoomGesture?: (newZoom: number) => any;
      containerClassName?: string;
      containerStyles?: CSSProperties;
      imageStyles?: CSSProperties;
      cursorMode?: CropperCursorMode;
      disableKeyboard?: boolean;
      disableMouse?: {
        all?: boolean;
        zoom?: boolean;
        pan?: boolean;
        draw?: boolean;
      boxInView?: { id?: string; rotate?: boolean; panInView?: boolean };

    All the above types have been exported from the module.


    • The onLoad prop is optional, but useful for a few things.
      1. To determine that the image has indeed loaded, same as an img tag.
      2. Get access to the internal fabric object.
      3. To get a resetCenter handler to reset the panned position of the image.
    • You need to pass a function the onCrop prop if you want the default functionality to work out of the box. It will be called when a drawing operation was completed. This will be needed if you want to receive the image payload after a cropping action was done.
      • It is however optional, in case you want the box drawing to be controlled externally.
    • The function supplied to onCrop will be called when a drawing operation was completed. This will be needed if you want to receive the image payload after a cropping action was done.
      • The first argument is a CropperEvent event that tells you all you need to know about the event that was triggered to cause this function to fire.
      • The second argument is a dictionary of's and their respective base64 encoded image contents.
    • Removed the ability to change a box after drawing it. The existing functionality was not stable enough to leave it, and leaving it in caused more issues than were manageable.
    • Mouse/Touchpad wheel to pan/zoom is supported. Example for wheel zoom is present in the examples/index.tsx.
    • Arrow Keys based pan/zoom is supported.
    • It would be advisable to memoize the functions passed to the component.
    • If you want to pass a box for reasons other than getting the imageData out of it, add the noImage: true key-val to it.


    npm i react-multi-cropper

    DownloadsWeekly Downloads






    Unpacked Size

    39.2 kB

    Total Files


    Last publish


    • jayantbh