From 66093e9c803f398b4d2dd83ed5f54dc0561a1c96 Mon Sep 17 00:00:00 2001 From: Vasilii Mikhailovskii Date: Tue, 19 Nov 2024 20:30:57 +0200 Subject: [PATCH] add label to qr-code --- public/images/logo.svg | 1 + src/utils/images/calculateFontSizeForText.ts | 24 ++++++ src/utils/images/convertImageToBlob.ts | 58 ++++++++++++++ src/utils/images/downloadImage.ts | 28 +++++++ src/views/ManageQRCodeReadyView.vue | 84 ++++++++++++++++++-- 5 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 public/images/logo.svg create mode 100644 src/utils/images/calculateFontSizeForText.ts create mode 100644 src/utils/images/convertImageToBlob.ts create mode 100644 src/utils/images/downloadImage.ts diff --git a/public/images/logo.svg b/public/images/logo.svg new file mode 100644 index 0000000..b6ec863 --- /dev/null +++ b/public/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/utils/images/calculateFontSizeForText.ts b/src/utils/images/calculateFontSizeForText.ts new file mode 100644 index 0000000..d96ad3b --- /dev/null +++ b/src/utils/images/calculateFontSizeForText.ts @@ -0,0 +1,24 @@ +export function calculateFontSizeForText(text: string, maxWidth: number): number { + // Создаем временный элемент для измерения текста + const span = document.createElement('span') + span.style.position = 'absolute' + span.style.whiteSpace = 'nowrap' + span.style.fontFamily = 'Arial, sans-serif' // Задаем нужный шрифт + span.style.visibility = 'hidden' + span.textContent = text + document.body.appendChild(span) + + // Начальный размер шрифта + let fontSize = maxWidth + span.style.fontSize = `${fontSize}px` + + // Уменьшаем размер шрифта, пока ширина текста не впишется в maxWidth + while (span.offsetWidth > maxWidth) { + fontSize -= 1 + span.style.fontSize = `${fontSize}px` + } + + // Удаляем временный элемент + document.body.removeChild(span) + return fontSize +} diff --git a/src/utils/images/convertImageToBlob.ts b/src/utils/images/convertImageToBlob.ts new file mode 100644 index 0000000..a49cd44 --- /dev/null +++ b/src/utils/images/convertImageToBlob.ts @@ -0,0 +1,58 @@ +export async function convertImageToBlob({ + url, + width, + height, + type, +}: { + url: string + width?: number // Ширина необязательна + height?: number // Высота необязательна + type: string +}): Promise { + if (!width && !height) { + throw new Error('Необходимо указать хотя бы одно значение: width или height.') + } + + return new Promise((resolve, reject) => { + const img = new Image() + + img.onload = () => { + // Вычисляем размеры, сохраняя пропорции + const aspectRatio = img.naturalWidth / img.naturalHeight + const targetWidth = width || height! * aspectRatio + const targetHeight = height || width! / aspectRatio + + // Создаем canvas и рисуем изображение + const canvas = document.createElement('canvas') + canvas.width = Math.round(targetWidth) + canvas.height = Math.round(targetHeight) + const context = canvas.getContext('2d') + + if (!context) { + return reject(new Error('Ошибка создания контекста')) + } + context.drawImage(img, 0, 0, canvas.width, canvas.height) + + // Конвертируем canvas в Blob + canvas.toBlob( + (blob) => { + if (blob) { + resolve(blob) + } else { + reject(new Error('Ошибка создания изображения')) + } + }, + type, + 1.0, + ) + + URL.revokeObjectURL(url) + } + + img.onerror = () => { + reject(new Error('Ошибка загрузки изображения')) + } + + img.src = url + }) +} diff --git a/src/utils/images/downloadImage.ts b/src/utils/images/downloadImage.ts new file mode 100644 index 0000000..1cbd57c --- /dev/null +++ b/src/utils/images/downloadImage.ts @@ -0,0 +1,28 @@ +import { convertImageToBlob } from './convertImageToBlob' + +export async function downloadImage({ + url, + width, + height, + filename, + type, +}: { + url: string + width?: number + height?: number + filename: string + type: string +}) { + try { + const blob = await convertImageToBlob({ url, width, height, type }) + + const link = document.createElement('a') + link.href = URL.createObjectURL(blob) + link.download = filename + link.click() + + URL.revokeObjectURL(link.href) // Очищаем URL после загрузки + } catch (err) { + console.error('Ошибка преобразования SVG в PNG:', err) + } +} diff --git a/src/views/ManageQRCodeReadyView.vue b/src/views/ManageQRCodeReadyView.vue index 0285102..82e1400 100644 --- a/src/views/ManageQRCodeReadyView.vue +++ b/src/views/ManageQRCodeReadyView.vue @@ -60,14 +60,20 @@