Cropper的一个demo

1.摸鱼大法第一招–Cropper

Cropper 就是基于canvas做的小插件,下面做的是一个图片裁剪,各位看官看看就行,有什么意见多提。

// A code block
import Cropper from 'cropperjs';
import 'cropper/dist/cropper.css'
import {useEffect, useState} from 'react';
import './tailor.css'
// import img1 from './images/fredrik-solli-wandem-EXBWaUeR4-g-unsplash.jpg';

/**
 * imgUrl: 当前选择的图片,
 * onReady: 剪切好后的回调函数
 * **/

const Tailor = function (props) {
    const { imgfile = '', onReady= () => {} } = props;
    //当前图片
    const [ tailPic, setTailPic ] = useState();
    //当前的Cropper
    const [ cropper, setCropper ] = useState();
    //当前的旋转角度
    const [ rotate, setRotate ] = useState('0');
    //是否开启预览
    const [ isPreview, setIsPreview ] = useState(false);

    useEffect(()=>{
        if( !imgfile ) return false;
        typeof imgfile === 'string' ? setTailPic(imgfile) : setTailPic( URL.createObjectURL(imgfile) )
    },[]);

    useEffect(() => {
        if( !tailPic ) return false;
        const img = document.getElementById('tailor_image');
        cropper?.destroy();
        img.src = tailPic;
        let option = {
            aspectRatio: 16 / 9,
            viewMode:1,
            dragMode: 'move', // 定义裁剪器的拖动模式。 移动画布
            guides:false,
            highlight:false,
            background:false,
            corp:(e)=>{
                console.log('eeee',e)
            }
        };
        option.preview = isPreview ? '.img_preview':'';
        const newCropper = new Cropper(img, option, []);
        setCropper(newCropper)
    },[tailPic, isPreview]);


    //取消
    const reset = ()=>{
        console.log('取消');
        setTailPic(props.imgfile)
    };

    //剪切
    const readied = async ()=>{
        let newPic = cropper?.getCroppedCanvas([{
            width:200,
            height:200
        }]).toDataURL('image/jpeg');
        setTailPic(newPic);
    };
    //旋转
    useEffect(()=>{
        console.log('旋转到', rotate);
        if( rotate === 360 || rotate === 0 ){
            setRotate(0);
            cropper?.reset()
        }else{
            cropper?.rotateTo(rotate)
        }
    },[ rotate ]);

    const cancle = () =>{
        // 返回上一页或者隐藏
    };

    const Ok = ()=>{
        // tailPic:当前剪辑的图片给 onReady 回调函数
        onReady()
    };
        return (
            <div className={'tailor'} >
                { imgfile ?
                    [
                        <div className={'tail_top'}>
                            <div className={'btn'} onClick={cancle}> 取消</div>
                            <div className={'btn'} onClick={() => {setIsPreview( !isPreview )}}>
                                {!isPreview ? '开启预览' : '关闭预览'}
                            </div>
                            <div className={'btn'} onClick={Ok}> 确定</div>
                        </div>,

                        <div className={'tail_middle'} id={'tail_middle'}>

                            <img
                                id={'tailor_image'}
                                alt={'剪切图片'}
                                className={'tailor_image'}
                            />

                        </div>,

                        <div className={'tail_buttom'}>
                            <div className={'btn'} onClick={reset}> 重置</div>
                            <div className={'btn'} onClick={() => {
                                setRotate(parseInt(rotate) + 90)
                            }}> 旋转
                            </div>
                            <div className="btn" onClick={readied}> 剪切</div>
                        </div>
                    ]
                    :
                    <div className={'empty'}>暂无内容</div>
                    }
                <div className={'img_preview'} />
            </div>
        )
};


export default Tailor;

css

// A code block


.tailor{
  width: 100vw;
  height: 100vh;
  overflow: auto;
  flex-direction: column;
  display: flex;
  background: #000;
  position: relative;
}

.img_preview{
  width: 150px;
  height: 150px;
  overflow: hidden;
  position: absolute;
  float: left;
  top: 60px;
  left: 40px;
  border-radius: 8px;
}

.btn{
  padding: 16px;
  color: #ffffff;
  font-size: 16px;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid;
}

.tail_top{
  height: 40px;
  padding: 8px;
  display: flex;
  justify-content: space-between;
}

.tail_middle{
  overflow: hidden;
  height: calc(100% - 112px);
  display: flex;
  justify-content: center;
  align-items: center;
}
.tailor_image{

}
.tail_buttom{
  height: 40px;
  padding: 8px;
  /*background: #ffffff;*/
  display: flex;
  justify-content: space-around;
}

.empty{
  width: 100%;
  height: 100%;
  color: #ffffff;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tailor_image{
  width: 100%;
}

.rotate >img{
  width: 32px;
  height: 32px;
}

效果图

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值