图片裁剪

This commit is contained in:
陈红丽 2024-09-02 17:19:46 +08:00
parent 1b7d40d2cc
commit 77d12a249c
3 changed files with 61 additions and 26 deletions

View File

@ -2,19 +2,37 @@
<div class="img-cropper" :class="{ 'img-cropper-auto': $slots.default, circled: circled }">
<slot name="default"></slot>
<template v-if="!$slots.default">
<template v-if="src">
<div class="img-cropper-img" @click="openCropper">
<img :src="src" :class="{ circled: circled }"/>
<div class="mask" :class="{ circled: circled }" @click.stop>
<div class="handle-icon" @click="openCropper">
<el-icon >
<Edit />
</el-icon>
</div>
<div class="handle-icon" @click="viewImg">
<el-icon>
<ZoomIn />
</el-icon>
</div>
<div class="handle-icon" @click="deleteImg">
<el-icon>
<Delete />
</el-icon>
</div>
</div>
</div>
</template>
<template v-else>
<div class="img-cropper-img" @click="openCropper">
<img :src="src" :class="{ circled: circled }" v-if="src"/>
<div class="addImg" v-else>
<div class="addImg">
<el-icon>
<plus />
</el-icon>
</div>
<div class="mask" :class="{ circled: circled }">
<el-icon class="el-input__icon">
<UploadOutlined />
</el-icon>
</div>
</div>
</template>
</template>
<CropperModal
ref="cropperRef"
@ -30,7 +48,6 @@
<script lang="ts" setup>
import { ref } from 'vue';
import CropperModal from './CropperModal.vue';
import { UploadOutlined } from '@vicons/antd';
import { cssUnit } from '@/utils';
const cropperRef = ref();
@ -39,7 +56,7 @@
title: { type: String, default: '图片上传' },
src: { type: String, required: true },
circled: { type: Boolean, default: false },
width: { type: [String, Number], default: 200 },
width: { type: [String, Number], default: 150 },
uploadApi: {
type: Function as PropType<(params) => Promise<any>>,
},
@ -50,9 +67,15 @@
const iconSize = cssUnit(Math.ceil(parseInt(getWidth) / 4));
const emit = defineEmits(['uploadSuccess']);
function handleSuccess(value){
emit('uploadSuccess',value)
}
const viewImg =()=>{
window.open(props.src)
}
const deleteImg = () => {
emit('uploadSuccess', {fileUrl:''});
};
function handleSuccess(value){
emit('uploadSuccess',value)
}
function openCropper() {
cropperRef.value.showModal();
}
@ -69,7 +92,7 @@ function handleSuccess(value){
overflow: hidden;
text-align: center;
position: relative;
&-img {
position: relative;
width: 100%;
@ -100,12 +123,20 @@ function handleSuccess(value){
left: 0;
top: 0;
opacity: 0;
padding: 0 6%;
transition: opacity 0.4s;
.el-icon {
color: #fff;
font-size: v-bind(iconSize);
}
.handle-icon {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 6%;
color: aliceblue;
.el-icon {
color: #fff;
font-size:20px;
}
}
}
&:hover {

View File

@ -1,5 +1,5 @@
<template>
<basicModal ref="modalRef" @register="modalRegister" @ok="handleOk">
<basicModal ref="modalRef" @register="modalRegister" @ok="handleOk" @close="handleClose">
<template #default>
<div class="cropper-box">
<div class="cropper-box-left">
@ -17,7 +17,7 @@
<el-upload
:show-file-list="false"
accept="image/*"
action="http://www.mocky.io/v2/5e4bafc63100007100d8b70f"
:http-request="handleHttpUpload"
:before-upload="beforeUpload"
style="width: auto"
>
@ -212,7 +212,8 @@
function showModal() {
openModal();
}
function handleHttpUpload(){
}
//
function beforeUpload(file) {
const reader = new FileReader();
@ -265,6 +266,10 @@
}
}
}
function handleClose(){
src.value =''
previewSource.value=''
}
return {
src,
@ -273,10 +278,12 @@
previewSource,
showModal,
beforeUpload,
handleHttpUpload,
handleCropend,
handleReady,
handlerToolbar,
handleOk,
handleClose
};
},
});

View File

@ -105,7 +105,7 @@
v-model:image-url="formData.avatar">
<template v-slot:tip>支持扩展名: jpg png jpeg;文件大小不超过200M</template>
</UploadImg> -->
<Cropper ref="cropperCircled" :src="formData.avatar" :uploadApi="upload" title="矩形头像上传" @uploadSuccess="uploadSuccess">
<Cropper ref="cropperCircled" :src="formData.avatar" :uploadApi="upload" title="头像上传" @uploadSuccess="uploadSuccess">
<template #avatar>
</template>
</Cropper>
@ -193,6 +193,7 @@ const passwordConfirmValidator = (
const uploadSuccess =(data)=>{
formData.avatar = data.fileUrl
formRef.value?.validateField("avatar");
}
const dialogClose = () => {
emit("update:visible", false);
@ -250,10 +251,6 @@ const getAllDict = async () => {
list = await getPositionAllList();
optionData.positionList = list ? list : [];
};
function cropperCircledImg() {
cropperCircled.value.openCropper();
}
onMounted(() => {
getAllDict()
if (props.userId) {