将 react-easy-crop 与 react-uploady 相结合

Combine react-easy-crop with react-uploady

我正在尝试结合 react-easy-crop.js with react-uploady.js but do not succeed. There is an example,其中 react-uploady 与 react-image-crop 相结合,我正在尝试使用 react-easy-cropper 进行调整。选择一张图片在裁剪器中显示然后按'UPLOAD CROPPED' I 运行 进入错误:

TypeError
Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'.

不知道如何进行。

显示此行为的代码框是 here

如何避免这个错误? react-easy-crop应该怎么用react-uploady来实现?

我不确定原始沙箱或适应 react-easy-crop 的问题是什么,但我能够轻松地将其适应所需的库(尽管不太喜欢它 UI,但我想每个人都有自己的感觉)

无论如何,这里有一个工作沙箱 react-easy-crophttps://codesandbox.io/s/react-uploady-crop-and-upload-with-react-easy-crop-5g7vw

这里包括我更新的预览项目:

const ItemPreviewWithCrop = withRequestPreSendUpdate((props) => {
  const {
    id,
    url,
    isFallback,
    type,
    updateRequest,
    requestData,
    previewMethods
  } = props;
  const [uploadState, setUploadState] = useState(UPLOAD_STATES.NONE);
  const [croppedImg, setCroppedImg] = useState(null);

  //data for react-easy-crop
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);

  const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => 
    setCroppedAreaPixels(croppedAreaPixels),
 []);

  const isFinished = uploadState === UPLOAD_STATES.FINISHED;

  useItemProgressListener(() => setUploadState(UPLOAD_STATES.UPLOADING), id);
  useItemFinalizeListener(() => setUploadState(UPLOAD_STATES.FINISHED), id);

  const onUploadCrop = useCallback(async () => {
    if (updateRequest && croppedAreaPixels) {
      const [croppedBlob, croppedUri] = await getCroppedImg(
        url,
        croppedAreaPixels
      );

      requestData.items[0].file = croppedBlob;

      updateRequest({ items: requestData.items });
      setCroppedImg(croppedUri);
    }
  }, [url, requestData, updateRequest, croppedAreaPixels]);

  const onUploadCancel = useCallback(() => {
    updateRequest(false);
    if (previewMethods.current?.clear) {
      previewMethods.current.clear();
    }
  }, [updateRequest, previewMethods]);

  return isFallback || type !== PREVIEW_TYPES.IMAGE ? (
    <PreviewImage src={url} alt="fallback img" />
  ) : (
    <>
      {requestData && uploadState === UPLOAD_STATES.NONE ? (
        <div className="crop-view">
          <div className="crop-container">
            <Cropper
              image={url}
              crop={crop}
              zoom={zoom}
              aspect={4 / 3}
              onCropChange={setCrop}
              onCropComplete={onCropComplete}
              onZoomChange={setZoom}
            />
          </div>
          <div className="controls">
            <input
              type="range"
              value={zoom}
              min={1}
              max={3}
              step={0.1}
              aria-labelledby="Zoom"
              onChange={(e) => {
                setZoom(e.target.value);
              }}
              className="zoom-range"
            />
          </div>
        </div>
      ) : (
        <PreviewImage src={croppedImg || url} alt="img to upload" />
      )}
      <PreviewButtons
        finished={isFinished}
        crop={crop}
        updateRequest={updateRequest}
        onUploadCancel={onUploadCancel}
        onUploadCrop={onUploadCrop}
      />
      <p>{isFinished ? "FINISHED" : ""}</p>
    </>
  );
});

变化非常无缝,只是使用不同的裁剪器,并根据它的外观和行为方式用稍微不同的 CSS 包装它。我从他们的示例中获取了图像裁剪代码:https://codesandbox.io/s/q8q1mnr01w?file=/src/cropImage.js