base_ui/components/other/ImageCropper.vue

80 lines
1.8 KiB
Vue
Raw Normal View History

2025-03-11 10:16:19 +00:00
<template>
<div>
<input type="file" accept="image/*" @change="onFileChange" />
<div v-if="imageSrc" class="cropper-container">
<img ref="image" :src="imageSrc" alt="Image to crop" />
</div>
<button v-if="imageSrc" @click="cropImage">Crop and Upload</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
const imageSrc = ref(null);
const image = ref(null);
let cropper = null;
const onFileChange = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
imageSrc.value = event.target.result;
initCropper();
};
reader.readAsDataURL(file);
}
};
const initCropper = () => {
if (cropper) {
cropper.destroy();
}
cropper = new Cropper(image.value, {
aspectRatio: 1, // Set aspect ratio (e.g., 1 for square)
viewMode: 1, // Restrict the crop box to the size of the image
});
};
const cropImage = () => {
if (cropper) {
const croppedCanvas = cropper.getCroppedCanvas();
croppedCanvas.toBlob((blob) => {
uploadImage(blob);
});
}
};
const uploadImage = async (blob) => {
const formData = new FormData();
formData.append('image', blob, 'cropped-image.png');
try {
const response = await $fetch('/api/upload', {
method: 'POST',
body: formData,
});
alert('Image uploaded successfully!');
console.log('Upload response:', response);
} catch (error) {
console.error('Error uploading image:', error);
alert('Error uploading image');
}
};
onBeforeUnmount(() => {
if (cropper) {
cropper.destroy();
}
});
</script>
<style scoped>
.cropper-container {
max-width: 100%;
margin-top: 20px;
}
</style>