1.安装依赖 npm install cropperjs
2.在components下创建Cropperjs.vue文件 复制下面代码
子组件
<template>
<div style="
position: fixed;
left: 0;
top: 0;
width: 100%;
height: calc(100% - 40px);
background: rgba(0, 0, 0, 1);
z-index: 10000;">
<img :src="props.imgUrl" ref='imgRef' class="cropper-img" style="" alt="" />
</div>
<div class="flex" style="width: 100%;height: 40px;position: fixed;left: 0;bottom: 0; background: #fff;">
<div @click="quit" class=' flex flex-ac flex-jc cor-6' style="width: 50%;">
取消
</div>
<div @click="sureSave" class=' flex flex-ac flex-jc ' style="width: 50%; color: #fff; background: rgb(216, 216, 216) linear-gradient(350deg, rgb(74, 168, 255) 0%, rgb(26, 102, 255) 100%);">
确定
</div>
</div>
</template>
<script setup>
// 引入cropperjs库与相关css
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.min.css";
import { watch, onMounted, ref,reactive,defineEmits} from "vue";
let imgRef = ref(null)
const props = defineProps({
imgUrl:{ //图片本地路径
type:String,
default:""
}
})
//emit 返回值 clipImg确认按钮携带参数 quit 返回按钮 不携带参数
const emit = defineEmits(['clipImg','quit']);
const cropperObj= reactive({
afterImg:'', //裁剪后的图片
myCropper:null //进行裁剪
})
onMounted(()=>{
// const image = document.getElementById('image');
console.log(imgRef.value)
cropperObj.myCropper = new Cropper(imgRef.value, {
aspectRatio: 1,//
viewMode:1,//
rotatable:false,//是否可以旋转图片。
cropBoxMovable:true,//是否允许通过拖动来移动裁剪框。
cropBoxResizable:false,//是否允许通过拖动来调整裁剪框的大小。
toggleDragModeOnDblclick:true,//是否允许双击切换图片容器拖拽模式
zoomOnTouch:true,//是否允许通过拖动来缩放图片。
movable:true,//是否可以移动图片。
autoCropArea:1,
// minContainerWidth:500,
// minContainerHeight:500,
minCropBoxWidth:200,
minCropBoxHeight:200,
fixedBox:true,
setDragMode:'move',
});
})
function base64ToFile(base64, filename) {
// 将base64的数据部分提取出来
const parts = base64.split(';base64,');
const contentType = parts[0].split(':')[1];
const raw = window.atob(parts[1]);
// 将原始数据转换为Uint8Array
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
// 使用Blob对象创建一个新的文件对象
const blob = new Blob([uInt8Array], {type: contentType});
// 创建一个虚拟的文件对象
const file = new File([blob], filename, {type: contentType});
return file;
}
const sureSave = () =>{
cropperObj.afterImg = cropperObj.myCropper.getCroppedCanvas({
imageSmoothingQuality: 'high'
}).toDataURL('image/jpeg')
//cropperObj.afterImg为base64格式 按需转化为 file 格式
emit('clipImg',base64ToFile(cropperObj.afterImg,1));//把裁剪的图片返回到父组件
}
const quit = () =>{
emit('quit')
}
</script>
<style scoped>
.cropper-img {
display: block;
object-fit: contain;
max-width: 100%;
width: 100%;
height: 100%;
}
.flex{
display: flex;
}
.flex-ac{
align-items: center;
}
.flex-jc{
justify-content: center;
}
.cor-6{
color: #666;
}
</style>
恭喜你 完成一大半
3.引入组件
和普通引入组件代码一样 直接引入就行
组件需要一个参数,就是你获取的本地临时url路径
就是长这样的参数给组件(blob:http://localhost:5173/f65e1c04-218a-49c0-b63f-edd0cf1cbb34)
然后就是接收组件返回给你的base64数据或者file 数据
然后丢给服务器 就完成了
<Cropperjs v-if='state.cropper' @clipImg="moveImg" @quit='state.cropper=false' :imgUrl='state.cropperUrl'></Cropperjs>
<script setup>
import Cropperjs from '../../components/Cropperjs.vue'
let state=reactive({
cropper:false,
cropperUrl:''
})
function moveImg(e){
pushVideo(e)//上传文件方法
state.cropper=false
}
</script>