我正在尝试构建 poc 以通过拖放(react-dropzne)上传图像,然后使用 react-easy-crop 裁剪相同的图像,但我无法将它们相互连接。使用裁剪的简单图像上传button
工作正常每当我将拖放道具应用于input
元素拖放不起作用时,我都会卡住
这是我的
///draganddrop.js
import React, { useState, useCallback,useEffect,useMemo } from "react";
import Cropper from "react-easy-crop";
import getCroppedImg from "../DropnCrop/cropImage";
import { useDropzone } from "react-dropzone";
const baseStyle = {
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: "20px",
borderWidth: 2,
borderRadius: 2,
borderColor: "#eeeeee",
borderStyle: "dashed",
backgroundColor: "#fafafa",
color: "#bdbdbd",
transition: "border .3s ease-in-out",
};
const activeStyle = {
borderColor: "#2196f3",
};
const acceptStyle = {
borderColor: "#00e676",
};
const rejectStyle = {
borderColor: "#ff1744",
};
const previewStyle = {
width: "75%",
height: "300px",
};
const Dragdrop = () => {
const [crop, setCrop] = useState({ x: 0, y: 0 });
const [zoom, setZoom] = useState(2);
const [croppedImage, setCroppedImage] = useState(null);
const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);
const [uploadedImage, setImage] = useState();
const [files, setFiles] = useState([]);
const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
setCroppedAreaPixels(croppedAreaPixels);
console.log(croppedArea);
}, []);
const onDrop = useCallback((acceptedFiles) => {
setFiles(
acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
)
);
}, []);
const onSelectFile = (e) => {
if (e.target.files && e.target.files.length > 0) {
const reader = new FileReader();
reader.addEventListener("load", () => setImage(reader.result));
reader.readAsDataURL(e.target.files[0]);
console.log(uploadedImage);
}
};
const showCroppedImage = useCallback(async () => {
try {
const croppedImage = await getCroppedImg(
uploadedImage,
croppedAreaPixels
);
setCroppedImage(croppedImage);
console.log(croppedImage);
} catch (e) {
console.error(e);
}
}, [croppedAreaPixels]);
const {
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject,
} = useDropzone({
onDrop,
accept: "image/jpeg, image/png",
});
useEffect(
() => () => {
files.forEach((file) => URL.revokeObjectURL(file.preview));
},
[files]
);
const style = useMemo(
() => ({
...baseStyle,
...(isDragActive ? activeStyle : {}),
...(isDragAccept ? acceptStyle : {}),
...(isDragReject ? rejectStyle : {}),
}),
[isDragActive, isDragReject, isDragAccept]
);
return (
<div>
<div {...getRootProps({ style })} >
<input
{...getInputProps()}
onChange={(e) => onSelectFile(e)}
/>
<div>Drag and drop your images here.</div>
</div>
{uploadedImage ? (
<>
<button onClick={showCroppedImage}>Crop</button>
<div
style={{
width: "100%",
height: "200px",
position: "relative",
background: "#333333",
}}
>
<Cropper
image={uploadedImage}
crop={crop}
zoom={zoom}
aspect={16 / 9}
onCropChange={setCrop}
onCropComplete={onCropComplete}
onZoomChange={setZoom}
/>
{croppedImage ? (
<img
style={{
}}
src={croppedImage}
/>
) : null}
</div>
</>
) : null}
</div>
);
};
export default Dragdrop;
///cropImage.js
export const createImage = (url) =>
new Promise((resolve, reject) => {
const image = new Image()
image.addEventListener('load', () => resolve(image))
image.addEventListener('error', (error) => reject(error))
image.setAttribute('crossOrigin', 'anonymous') // needed to avoid cross-origin issues on CodeSandbox
image.src = url
})
export function getRadianAngle(degreeValue) {
return (degreeValue * Math.PI) / 180
}
/**
* Returns the new bounding area of a rotated rectangle.
*/
export function rotateSize(width, height, rotation) {
const rotRad = getRadianAngle(rotation)
return {
width:
Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height),
height:
Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height),
}
}
/**
* This function was adapted from the one in the ReadMe of https://github.com/DominicTobias/react-image-crop
*/
export default async function getCroppedImg(
imageSrc,
pixelCrop,
rotation = 0,
flip = { horizontal: false, vertical: false }
) {
const image = await createImage(imageSrc)
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) {
return null
}
const rotRad = getRadianAngle(rotation)
// calculate bounding box of the rotated image
const { width: bBoxWidth, height: bBoxHeight } = rotateSize(
image.width,
image.height,
rotation
)
// set canvas size to match the bounding box
canvas.width = bBoxWidth
canvas.height = bBoxHeight
// translate canvas context to a central location to allow rotating and flipping around the center
ctx.translate(bBoxWidth / 2, bBoxHeight / 2)
ctx.rotate(rotRad)
ctx.scale(flip.horizontal ? -1 : 1, flip.vertical ? -1 : 1)
ctx.translate(-image.width / 2, -image.height / 2)
// draw rotated image
ctx.drawImage(image, 0, 0)
// croppedAreaPixels values are bounding box relative
// extract the cropped image using these values
const data = ctx.getImageData(
pixelCrop.x,
pixelCrop.y,
pixelCrop.width,
pixelCrop.height
)
// set canvas width to final desired crop size - this will clear existing context
canvas.width = pixelCrop.width
canvas.height = pixelCrop.height
// paste generated rotate image at the top left corner
ctx.putImageData(data, 0, 0)
// As Base64 string
// return canvas.toDataURL('image/jpeg');
// As a blob
return new Promise((resolve, reject) => {
canvas.toBlob((file) => {
resolve(URL.createObjectURL(file))
}, 'image/jpeg')
})
}