实现效果
在Upload上传前,对图片进行裁剪,裁剪完毕后,再交给Upload完成上传。
实现方式
- 在Upload的beforeUpload中调起react-cropper进行图片裁剪;
- 将拿到的图片传给react-cropper;
- 利用react-cropper进行裁剪;
- 将裁剪后的图片交给Upload完成上传。
需要解决的问题
- 如何在beforeUpload中调起react-cropper组件;
- 裁剪后的图片如何再交给Upload组件。
解决方式
- 将react-cropper组件放在Modal弹框中,在beforeUpload方法中,调出弹框。
- Upload的beforeUpload中,支持返回一个 Promise 对象,resolve 时开始上传,resolve可以接收file或blob对象。
- beforeUpload返回的Promise中设置一个定时器,每隔一段时间,查询一下裁剪是否完成。
- 设置一个标志位,表示裁剪是否完成。
具体的代码
react-cropper组件
import React, {Component} from 'react'
import { Button } from 'antd'
import Cropper from 'react-cropper'
class CropperDemo extends Component {
_crop(){}
handleOk = () => {
//将裁剪的图片转成blob对象
this.refs.cropper.getCroppedCanvas().toBlob((blob) => {
this.props.onOk(blob);
},"image/png");
}
render() {
const { src } = this.props;
return (
<div className="cropper-wrap">
<Cropper
ref='cropper'
src={src}
style={{height: 400, width: '100%'}}
aspectRatio={16 / 9}
guides={false}
crop={this._crop.bind(this)}
/>
<Button onClick={this.handleOk}>确认</Button>
</div>
);
}
}
引用react-cropper组件的代码
// 弹框代码
<Modal visible={cropVisible} footer={null} onCancel={this.handleCropCancel}>
<Cropper src={cropSrc} onOk={this.handleOk} />
</Modal>
// onOk方法
handleOk = (dataUrl) => {
this.setState({
cropVisible: false
});
this.blob= dataUrl; // this.blob既是裁剪后的图片,也可以作为裁剪结束的标志
}
beforeUpload 代码
beforeUpload = (file) => {
let imageType = ['image/jpeg','image/png','image/jpg','image/gif'];
let isImage = imageType.findIndex(o => o === file.type) !== -1;
if (!isImage) {
message.error('请选择正确的图片类型!');
return false;
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不能超过2M!');
return false;
}
let reader = new FileReader();
reader.readAsDataURL(file);
let _this = this;
reader.onload = (e) => {
_this.setState({
cropSrc: e.target.result,
cropVisible: true,
})
}
return new Promise((resolve, reject) => {
let index = setInterval(() => {
if(this.blob){ // 监听裁剪是否完成
window.clearInterval(index);
this.blob.uid = file.uid; // 需要给裁剪后的blob对象设置uid,否则会报错!!!
resolve(this.blob); // 执行后续的上传操作
}
},100);
});
}
利用了setInterval 监听裁剪是否完成,完成后Upload就可以完成后续的上传操作。
好处是不用单独写一个上传方法去,上传裁剪后的图片,整个上传都由Upload完成。