antd的Upload上传组件,搭配react-cropper实现图片的裁剪上传

实现效果
在Upload上传前,对图片进行裁剪,裁剪完毕后,再交给Upload完成上传。

实现方式

  1. 在Upload的beforeUpload中调起react-cropper进行图片裁剪;
  2. 将拿到的图片传给react-cropper;
  3. 利用react-cropper进行裁剪;
  4. 将裁剪后的图片交给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完成。

你可能感兴趣的:(antd的Upload上传组件,搭配react-cropper实现图片的裁剪上传)