0.1.16-fabric • Published 3 years ago

react-multi-cropper v0.1.16-fabric

Weekly downloads
88
License
MIT
Repository
github
Last release
3 years ago

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.

screenshot

Installation

yarn add react-multi-cropper fabric

Development

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.

Usage

See the examples/index.tsx file.

Functionality

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.

Documentation

Default Usage

const Cropper = ({ imageUrl }: { imageUrl: string ) => {
  const [boxes, setBoxes] = useState<CropperBox[]>([]);
  const [imageMap, setImageMap] = useState<CropperBoxDataMap>({});

  const updateBoxes = (_, __, _boxes) => setBoxes(_boxes);

  return (
    <div>
      <MultiCrops
        src={imageUrl}
        zoom={1}
        boxes={boxes}
        onChange={updateBoxes}
        onCrop={(e, map) => setImageMap(map)}
        onLoad={(map) => setImageMap(map)}
      />
      {boxes.map((box, i) =>
        !!imageMap[box.id] && <img src={imageMap[box.id]} key={i} />
      )}
    </div>
  );
};

How to reset zoom, rotation, and pan?

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

const reset = () => {
  setRotation(0);
  setZoom(1);
  resetCenter();
};

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
resetCenter();

// Obtain the function from onLoad
onLoad={(map, reset) => {
  setImageMap(map);
  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.

Notes:

  • 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 box.id'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.
0.1.16-fabric

3 years ago

0.1.15-fabric

3 years ago

0.1.14-fabric

3 years ago

0.1.13-fabric

3 years ago

0.1.12-fabric

4 years ago

0.1.11-fabric

4 years ago

0.1.10-fabric

4 years ago

0.1.9-fabric

4 years ago

0.1.8-fabric

4 years ago

0.1.6-fabric

4 years ago

0.1.7-fabric

4 years ago

0.1.5-fabric

4 years ago

0.1.4-fabric

4 years ago

0.1.3-fabric

4 years ago

0.1.2-fabric

4 years ago

0.1.1-fabric

4 years ago

0.1.0-fabric

4 years ago

0.9.6

4 years ago

0.9.5

4 years ago

0.9.4

4 years ago

0.9.3

4 years ago

0.9.2

4 years ago

0.9.1

4 years ago

0.9.0

4 years ago

0.8.6

4 years ago

0.8.5

4 years ago

0.8.4

4 years ago

0.8.3

4 years ago

0.8.2

4 years ago

0.8.1

4 years ago

0.8.0

4 years ago

0.7.6

4 years ago

0.7.5

4 years ago

0.7.4

4 years ago

0.7.2

4 years ago

0.7.3

4 years ago

0.7.1

4 years ago

0.7.0

4 years ago

0.6.1-0

4 years ago

0.6.0

4 years ago

0.6.0-2

4 years ago

0.6.0-1

4 years ago

0.6.0-0

4 years ago

0.5.2

4 years ago

0.5.3

4 years ago

0.5.2-0

4 years ago

0.5.1

4 years ago

0.5.0

4 years ago

0.4.7

4 years ago

0.4.6

4 years ago

0.4.5

4 years ago

0.4.4

4 years ago

0.4.3

4 years ago

0.4.3-0

4 years ago

0.4.2

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.0

4 years ago

0.2.5

4 years ago

0.2.3

4 years ago

0.2.4

4 years ago

0.2.1

4 years ago

0.2.2

4 years ago

0.2.0

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago

0.0.10

4 years ago

0.0.11

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.5

4 years ago

0.0.6

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago