常用的文件上传场景 https://juejin.cn/post/6980142557066067982

ReactImageCrop裁剪图片
https://github.com/DominicTobias/react-image-crop
npm i react-image-crop
function CropDemo({ src }) {const [crop, setCrop] = useState({ aspect: 16 / 9 });return <ReactCrop src={src} crop={crop} onChange={newCrop => setCrop(newCrop)} />;}
裁剪图片demo
https://codesandbox.io/s/react-image-crop-demo-with-react-hooks-y831o?file=/src/App.js:0-3132
import React, { useState, useCallback, useRef, useEffect } from 'react';import ReactCrop from 'react-image-crop';import 'react-image-crop/dist/ReactCrop.css';function App() {const [upImg, setUpImg] = useState();const imgRef = useRef(null);const previewCanvasRef = useRef(null);const [crop, setCrop] = useState({ unit: '%', width: 30, aspect: 16 / 9 });const [completedCrop, setCompletedCrop] = useState(null);const onSelectFile = (e) => {if (e.target.files?.length > 0) {const reader = new FileReader();reader.addEventListener('load', () => setUpImg(reader.result));reader.readAsDataURL(e.target.files[0]);}};const onLoad = useCallback((img) => {imgRef.current = img;}, []);useEffect(() => {if (!completedCrop || !previewCanvasRef.current || !imgRef.current) {return;}const image = imgRef.current;const canvas = previewCanvasRef.current;const crop = completedCrop;const scaleX = image.naturalWidth / image.width;const scaleY = image.naturalHeight / image.height;const ctx = canvas.getContext('2d');const pixelRatio = window.devicePixelRatio;canvas.width = crop.width * pixelRatio;canvas.height = crop.height * pixelRatio;ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);ctx.imageSmoothingQuality = 'high';ctx.drawImage(image,crop.x * scaleX,crop.y * scaleY,crop.width * scaleX,crop.height * scaleY,0,0,crop.width,crop.height);}, [completedCrop]);return (<div className="App"><div><input type="file" accept="image/*" onChange={onSelectFile} /></div><ReactCropsrc={upImg}onImageLoaded={onLoad}crop={crop}onChange={(c) => setCrop(c)}onComplete={(c) => setCompletedCrop(c)}/><div><canvasref={previewCanvasRef}// Rounding is important so the canvas width and height matches/is a multiple for sharpness.style={{width: Math.round(completedCrop?.width ?? 0),height: Math.round(completedCrop?.height ?? 0)}}/></div><p>Note that the download below won't work in this sandbox due to theiframe missing 'allow-downloads'. It's just for your reference.</p><buttontype="button"disabled={!completedCrop?.width || !completedCrop?.height}onClick={() =>generateDownload(previewCanvasRef.current, completedCrop)}>下载图片</button></div>);}export default App;// 下载图片function generateDownload(canvas, crop) {if (!crop || !canvas) {return;}canvas.toBlob((blob) => {const previewUrl = window.URL.createObjectURL(blob);const anchor = document.createElement('a');anchor.download = 'cropPreview.png';anchor.href = URL.createObjectURL(blob);anchor.click();window.URL.revokeObjectURL(previewUrl);},'image/png',1);}
antd-img-crop图片裁剪
基于 react-easy-crop和 antd Modal的图片上传封装
图片裁剪是基于 Modal的弹窗,缺点
- 没有设置 mask: false,如果页面上有 Modal了,上传图片会有 mask覆盖
在线demo https://codesandbox.io/s/antd-img-crop-4qoom5p9x4?file=/src/index.jsyarn add antd-img-crop
在线源码 https://github.com/nanxiaobei/antd-img-crop/blob/master/src/index.jsx
属性
```jsx
import React, { useState } from ‘react’;
import { Upload } from ‘antd’;
import ImgCrop from ‘antd-img-crop’;
function ImageCrop() { const [fileList, setFileList] = useState([ { uid: ‘-1’, url: ‘https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png‘, }, ]);
const onChange = ({ fileList: newFileList }) => { setFileList(newFileList); };
const onPreview = async (file) => { let src = file.url; if (!src) { src = await new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(file.originFileObj); reader.onload = () => resolve(reader.result); }); } const image = new Image(); image.src = src; const imgWindow = window.open(src); imgWindow.document.write(image.outerHTML); };
return (
export default ImageCrop;
<a name="CI3L6"></a>### react-easy-cropantd-img-crop就是对 react-easy-crop的封装<br />[https://github.com/ricardo-ch/react-easy-crop](https://github.com/ricardo-ch/react-easy-crop)```bashyarn add react-easy-crop

