头像图片上传和裁切
<script setup>
import { message } from 'ant-design-vue'
import Cropper from 'cropperjs'
import { upload } from '@/api/workOrder/hotService'
const props = defineProps({
modelValue: String,
})
const emit = defineEmits(['update:modelValue', 'submit'])
const modelValue = useVModel(props, 'modelValue', emit)
const [visible, toggle] = useToggle(false)
const imgRef = ref()
const previewRef = ref()
const fileRef = ref()
const cropper = ref()
function init() {
cropper.value = new Cropper(unrefElement(imgRef), {
aspectRatio: 1,
dragMode: 'move',
preview: unrefElement(previewRef),
restore: false,
center: false,
highlight: false,
cropBoxMovable: true,
toggleDragModeOnDblclick: true,
})
}
function getImageBase64(e) {
const file = e.target.files[0]
if (!file) return
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
if (!cropper.value) init()
cropper.value.replace(reader.result)
}
}
function submit() {
const file = cropper.value?.getCroppedCanvas()?.toDataURL()
if (!file) {
message.info('请选择图片')
return
}
if (file.length > 250 * 1024) {
message.warning('选择的区域太大,超过了250K。请缩小选择区域!')
return
}
modelValue.value = file
let newfile = base64ToFile(file, '头像')
const formData = new window.FormData()
formData.append('files', newfile)
upload(formData).then((res) => {
if (res?.code == 200) {
message.success('上传成功')
if (res.data && res.data !== null && res.data.length) {
emit('submit', res.data)
}
}
})
toggle(false)
}
function base64ToFile(dataurl, filename) {
let arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
function upload1() {
fileRef.value?.click()
}
function reset() {
cropper.value?.reset()
}
function remove() {
cropper.value?.destroy()
cropper.value = null
}
function zoomIn() {
cropper.value?.zoom(0.1)
}
function zoomOut() {
cropper.value?.zoom(-0.1)
}
</script>
<template>
<div>
<div class="btn">
<a-button @click="toggle()">本地上传</a-button>
</div>
<a-modal
v-model:visible="visible"
title="修改头像"
width="640px"
:closable="false"
:maskClosable="false"
@ok="submit()"
>
<div class="flex justify-between">
<div class="w-96 border border-solid border-gray-300">
<img ref="imgRef" />
</div>
<div class="flex flex-col items-center space-y-2.5">
<div
ref="previewRef"
class="w-44 h-44 border border-solid border-gray-300 overflow-hidden"
/>
<a-space>
<a-button-group>
<input
ref="fileRef"
type="file"
accept="image/png, image/jpeg, image/gif, image/jpg"
class="hidden"
@change="getImageBase64"
/>
<a-button type="primary" @click="upload1()">
<template #icon>
<UploadOutlined />
</template>
</a-button>
<a-button type="primary" @click="reset()">
<template #icon>
<SyncOutlined />
</template>
</a-button>
<a-button type="primary" @click="remove()">
<template #icon>
<DeleteOutlined />
</template>
</a-button>
</a-button-group>
<a-button-group>
<a-button type="primary" @click="zoomIn()">
<template #icon>
<ZoomInOutlined />
</template>
</a-button>
<a-button type="primary" @click="zoomOut()">
<template #icon>
<ZoomOutOutlined />
</template>
</a-button>
</a-button-group>
</a-space>
</div>
</div>
</a-modal>
</div>
</template>
<style scoped>
@import 'cropperjs';
img {
display: block;
max-width: 100%;
}
.btn {
margin-top: 10px;
}
</style>

浙公网安备 33010602011771号