将 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-crop:https://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
我正在尝试结合 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-crop:https://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