react+antd+react-cropper裁剪图片组件封装

tip:之前写了一个裁剪 但是有bug(参考之前的文章) 现在又遇见这个功能 终究是躲不过了 现已解决之前出现的bug 整理代码并封装成了组件 供大家参考使用 避免踩雷
notice:react版本:15.4.0(博主使用版本,版本的不同,代码可稍作修改)

1.Cropper.js

import React, { Component } from 'react'
import { Button, message,Icon} from 'antd';
import Cropper from 'react-cropper' // 引入Cropper
import 'cropperjs/dist/cropper.css' // 引入Cropper对应的css
import './Cropper.less';

export default class ClassCropperModal extends Component {
  constructor(props) {
    super(props)
    this.state = {
      src: null
    }
  }

  componentDidMount() {
    const fileReader = new FileReader()
    fileReader.onload = e => {
      const dataURL = e.target.result
      this.setState({ src: dataURL })
    }

    fileReader.readAsDataURL(this.props.uploadedImageFile)
  }

  handleSubmit = () => {
    if (!this.state.submitting) {
      // let url = `/homepage_images` // 你要上传的url
      // 拿到文件名
      // let filename = this.props.uploadedImageFile.name

      console.log('正在上传图片')
      // TODO: 这里可以尝试修改上传图片的尺寸
      this.cropper.getCroppedCanvas().toBlob(async blob => {
        // // 创造提交表单数据对象
        // const formData = new FormData()
        // // 添加要上传的文件
        // formData.append('file', blob, filename)
        // 提示开始上传 (因为demo没有后端server, 所以这里代码我注释掉了, 这里是上传到服务器并拿到返回数据的代码)
        // this.setState({submitting: true})
        // 上传图片
        // const resp = await http.post(url, formData)
        // 拿到服务器返回的数据(resp)
        // console.log(resp)
        // 提示上传完毕
        // this.setState({submitting: false})

        //把选中裁切好的的图片传出去
        this.props.onSubmit(blob);

        // 关闭弹窗
        this.props.onClose()
      })
    }
  }

  render() {
    const {option} = this.props;
    return (
      

裁剪

{this.props.onClose()}}/>
{ this.state.src ?
(this.cropper = cropper)} // Cropper.js options viewMode={option.viewMode}//定义cropper的视图模式,1代表限制裁剪框不超过画布大小 zoomable={option.zoomable}//是否允许放大图像,默认为true aspectRatio={option.aspectRatio} // 固定为1:1 可以自己设置比例, 默认情况为自由比例 guides={option.guides}//显示在裁剪框上方的虚线 默认为true preview=".cropper-preview"//指定类名为.cropper-preview的div作为预览的窗口 minCropBoxHeight={option.minCropBoxHeight} minCropBoxWidth={option.minCropBoxWidth} />
{/* 预览 */} {/*
*/}
: '' }
) } }

2.Cropper.less

.class-cropper-modal {
    position: fixed;
    background-color:rgba(0, 0, 0, 0.45);
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1;
    .modal-center{
      width: 625px;
      background-color: #ffffff;
      border-radius: 4px;
    }
    .class-cropper-header{
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 16px;
      color: rgba(0, 0, 0, 0.85);
      height: 57px;
      padding: 20px 30px;
      box-sizing: border-box;
      border-bottom: 1px solid #F4F4F4;
      .anticon{
        color: rgba(0, 0, 0, 0.85);
        font-size: 16px;
        cursor: pointer;
      }
    }
    .modal-panel {
      width: 625px;
      height: 595px;
      background: white;
      padding: 20px 62px;
      display: flex;
      flex-direction: column;
      align-items: stretch;
  
      .button-row {
        height: 50px;
        flex-shrink: 0;
        display: flex;
        justify-content: center;
        
      }
    
      .cropper-container-container {
        flex: 1;
        display: flex;
        align-items: stretch;
        justify-content: space-between;
        height: 100%;
  
        .cropper-container {
          flex: 0 0 501px;
          margin-right: 20px;
          .cropper {
            width: 100%;
            height: 100%;
          }
        }
        .preview-container {
          flex: 1;
          display: flex;
          align-items: flex-end;
          .cropper-preview {
            width: 180px;
            height: 180px;
            overflow: hidden;
            border: 1px solid #383838;
          }
        }
      }
    }
    .submit-button {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding: 10px 30px;
      height: 100%;
      color: #383838;
      font-size: 14px;
      border-top: 1px solid #F4F4F4;
    }
  }

utils.js

//图片转base64位
export function getBase64(img, callback) {
    const reader = new FileReader();
    reader.readAsDataURL(img);
    return new Promise(function(resolve){
        reader.addEventListener('load', () => callback(resolve(reader.result)));
    })
}

3.使用

import React, { Component } from 'react';
import { Button, Switch, InputNumber, message,Radio,Input,Slider,Icon,Upload,Popover,Spin } from 'antd';
import config from '../../config.js';
import request from '../../utils/request';
import {getBase64} from '../../utils/utils.js';
import CropperImg from '../Cropper/Cropper';
class InviteDefine extends Component {
    constructor(props) {
        super(props);
        this.state = {
            classModalVisible: false,
            classModalFile: null,//上传文件
            classResultImgUrl: null,//剪辑文件后的地址
        };
    }
  beforeUpload=(file)=> {
        let files = [];
            this.setState({
                fileList: [...files]
            })
             return false;
    }
uploadOptionPic(file){
            this.setState({
                    classModalFile:file.file
                },()=>{
                    this.setState({
                        classModalVisible:true
                    })
                })
}
handleGetResultImgUrl = key => blob => {
        //裁剪后的图片
        let strUrl = '';
        getBase64(blob, str => strUrl = str).then((value)=>{
            let data = {
               value
            }
            //把blob转为可访问的url地址
            request(`xxxx/base64Save`, {
                method: 'POST',
                // headers: config.headers,
                headers: {'Content-Type':'application/json'},
                credentials: "include",
                body: config.parseJson(data)
            }).then((res) => {
                //获取到图片链接
        })
  }
}
  render(){
    const {classModalVisible,classModalFile} = this.state;
    const uploadButton = (
            

添加自定义背景

); return(
{ uploadButton } {classModalVisible && ( { this.setState({ classModalVisible: false,editClassModalVisible:false }) }} onSubmit={this.handleGetResultImgUrl} option={{minCropBoxHeight:1334,minCropBoxWidth:750,aspectRatio:1/1.792,zoomable:true,guides:false,viewMode:1,className:'cropper'}} visible={classModalVisible} /> )}
) }

你可能感兴趣的:(react+antd+react-cropper裁剪图片组件封装)