一. 需求:最近项目中遇到要进行图片裁剪的需求,采用了cropperjs进行二次图片裁剪组件封装。在这里记录下二次封装过程。
二. 二次封装代码:
import React, { useState, MouseEvent, FunctionComponent } from 'react';
import styles from './index.less';
import Cropper from 'cropperjs';
import { Button } from '@pyramid-kit/mobile';
/**
* 图片剪切
* 参考:https://github.com/fengyuanchen/cropperjs
* @param props
*/
interface IProps {
/** 获取图片配置选项 */
options?: Cropper.GetCroppedCanvasOptions;
/** 是否显示 */
visible?: boolean;
/** 待剪切的原始图片 */
url?: string;
/** 剪切完成 */
onCropSuccess?: (dataUrl: string) => void;
/** 取消 */
onCancel?: () => void;
}
const Cropping: FunctionComponent<IProps> = (props) => {
const { visible = false, url = '', onCropSuccess = () => { }, onCancel = () => { } } = props;
// 图片裁剪实例
const [cropper, setCropper] = useState<Cropper>();
// 初始化待裁剪图片
const onLoadImg = (e: MouseEvent<HTMLImageElement>) => {
const ins = new Cropper(e.currentTarget, {
aspectRatio: 1 / 1, // 宽高比
viewMode: 1, // 视图控制:1-限制裁剪框不能超出图片的范围
dragMode: 'move', // 拖拽模式:move-图片可移动
autoCropArea: 1, // 裁剪区域占图片的大小(0~1)
cropBoxMovable: true, // 是否可以拖拽剪切框
cropBoxResizable: true, // 是否可以改变剪切框的尺寸
background: false, // 是否显示网格状背景
scalable: false, // 是否可以缩放图片(改变宽高)
toggleDragModeOnDblclick: false, // 是否可以通过双击切换拖拽图片模式
});
setCropper(ins);
};
// 点击完成
const cropComplete = () => {
const data = cropper?.getCroppedCanvas();
if (data) {
onCropSuccess?.call(null, data.toDataURL());
}
};
return (visible ?
<div className={styles.crop_box}>
{/* 45为头部的高度(可能需要判断是否显示头部),65为底部的高度 */}
<div style={{ height: document.documentElement.clientHeight - 45 - 65 }}>
<img src={url} onLoad={(e: MouseEvent<HTMLImageElement>) => { onLoadImg(e); }} alt="" />
</div>
<div className={styles.crop_box_actions}>
<Button onClick={() => onCancel?.call(null)}>取消</Button>
<Button type="primary" onClick={() => { cropComplete(); }}>完成</Button>
</div>
</div> : null
);
};
export default Cropping;
三. 样式代码:
.crop_box {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9000;
background-color: #fff;
overflow: hidden;
display: flex;
flex-direction: column;
&_actions {
display: flex;
justify-content: space-between;
background-color: #fff;
border-top: 1px solid #ddd;
padding: 36px 12px;
button {
display: block;
height: 40px;
width: 100%;
&+button {
margin-left: 12px;
}
}
}
:global {
.cropper-container {
flex: 1;
}
}
}
四. 效果:
![基于React的图片裁剪组件](https://i-blog.csdnimg.cn/blog_migrate/0c45bdd5ce252f3ffc36e0bce9ee5368.png)