- Référencement de l'élément canvas
Nous utilisons la directive ref pour référencer notre élément canvas, ce qui nous permet d'appeler directement ses méthodes.
<template>
<canvas ref="canvasRef" :width="489" :height="34" style="width: 489px;height: 34px;background-color: pink">
</canvas>
</template>
// Obtenir la référence de l'élément canvas
const canvasRef = ref(null)
- Sélection d'une image locale
Lorsqu'une image est sélectionnée, nous appelons immédiatement notre fonction de traitement canvas. Il est crucial d'atetndre le chargement complet de l'image avant de la traiter, d'où l'utilisation de l'événement onload.
<label class="btn" for="fileInput">Sélectionner un fichier image</label>
<input
type="file"
id="fileInput"
ref="fileInputRef"
style="position: absolute; clip: rect(0 0 0 0)"
accept="image/png, image/jpeg, image/gif, image/jpg"
@change="handleImageSelection($event)"
/>
Dans notre setup, nous définissons les options nécessaires :
const imageOptions = reactive({
source: '', // URL de l'image source
})
// Gestion de la sélection d'image
const handleImageSelection = function(event) {
if(!event.target.files.length) return;
// Validation du type de fichier
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(event.target.value)) {
alert('Types d\'image acceptés : jpeg, jpg, png');
return false;
}
const file = event.target.files[0];
const fileNameParts = file.name.split('.');
const selectedImageType = fileNameParts[fileNameParts.length-1];
const reader = new FileReader();
reader.onload = (e) => {
let imageData;
if (typeof e.target.result === 'object') {
imageData = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
imageData = e.target.result;
}
imageOptions.source = imageData;
// Appel du traitement canvas
processCanvasImage();
};
// Conversion en base64
reader.readAsDataURL(file);
}
- Traitement Canvas : compression, positionnement et préparation au téléversement
Voici comment nous utilisons Canvas pour compresser et positionner notre image :
const processCanvasImage = () => {
// Récupération du contexte canvas
const context = canvasRef.value.getContext("2d");
// S'il y a déjà une image traitée, on efface le canvas
if(processedImageData.value) {
context.clearRect(0, 0, 489, 34);
processedImageData.value = "";
}
// Création de l'objet image
const image = new Image();
image.src = imageOptions.source;
// Traitement après chargement de l'image
image.onload = () => {
// Dimensions originales
const originalWidth = image.width;
const originalHeight = image.height;
// Calcul des nouvelles dimensions (hauteur fixe à 34px)
const scaledWidth = 34 * originalWidth / originalHeight;
const scaledHeight = 34;
// Calcul de la position horizontale pour centrer l'image
const horizontalOffset = (489 - scaledWidth) / 2;
// Dessin de l'image sur le canvas
context.drawImage(image, horizontalOffset, 0, scaledWidth, scaledHeight);
// Conversion en base64
processedImageData.value = canvasRef.value.toDataURL();
};
}
- Convresion en Blob et téléversement
Une fois l'image traitée, nous la convertissosn en Blob pour la téléverser :
const uploadProcessedImage = () => {
canvasRef.value.toBlob(async (blobData) => {
const formData = new FormData();
formData.append('imageFile', blobData, `LOGO.${selectedImageType.value}`);
formData.append('hospitalId', hospitalData.value.id);
// Indicateur de chargement
isUploading.value = true;
// Appel API de téléversement
uploadImage(formData).then(response => {
if (response.code === 200) {
showNotification("Image téléversée avec succès", 'success');
refreshHospitalData();
isUploading.value = false;
} else {
showNotification(response.msg || "Erreur lors du téléversement", 'error');
isUploading.value = false;
}
}).catch(error => {
showNotification("Erreur réseau", 'error');
isUploading.value = false;
});
});
}
Fonction utilitaire pour les notifications :
const showNotification = (message, type) => {
ElMessage({
message: message,
type: type,
showClose: true,
duration: 2000,
});
};