Большой редизайн

This commit is contained in:
Ilia Miheev
2026-06-20 14:21:40 +03:00
parent a90db0d7dc
commit 47fe6c966c
3 changed files with 819 additions and 143 deletions
+67 -40
View File
@@ -1,6 +1,11 @@
import { ref, nextTick } from 'vue'
import QRCode from 'qrcode'
const BASE_QR_SIZE = 256
const MAX_WIDTH_RATIO = 0.8
const MIN_SCALE = 0.5
const SCALE_STEP = 0.1
export function useQrCode() {
const textInput = ref('')
const error = ref('')
@@ -8,17 +13,41 @@ export function useQrCode() {
const scale = ref(1)
const hasQr = ref(false)
const qrCanvasRef = ref(null)
const qrFrameRef = ref(null)
function logMessage(message, color = 'red') {
error.value = message
errorColor.value = color
}
function applyScale() {
function getFrameWidth() {
return qrFrameRef.value?.getBoundingClientRect().width ?? 0
}
function getMaxWidth() {
return window.innerWidth * MAX_WIDTH_RATIO
}
function persistScale() {
localStorage.setItem('scale', String(scale.value))
}
async function renderQrCanvas() {
const canvas = qrCanvasRef.value
if (!canvas) return
canvas.style.transform = `scale(${scale.value})`
canvas.style.transformOrigin = 'top'
const userText = textInput.value.trim()
if (!canvas || !userText) return
const width = Math.round(BASE_QR_SIZE * scale.value)
await QRCode.toCanvas(canvas, userText, { width })
}
async function clampScaleIfNeeded() {
await nextTick()
if (getFrameWidth() > getMaxWidth()) {
scale.value = 1
persistScale()
await renderQrCanvas()
}
}
async function generateQR() {
@@ -34,15 +63,9 @@ export function useQrCode() {
await nextTick()
try {
await QRCode.toCanvas(qrCanvasRef.value, userText)
await renderQrCanvas()
logMessage('')
applyScale()
const canvasWidth = qrCanvasRef.value.getBoundingClientRect().width
if (canvasWidth > window.innerWidth * 0.8) {
scale.value = 1
applyScale()
}
await clampScaleIfNeeded()
} catch (err) {
console.error(err)
logMessage('Ошибка при генерации QR-кода.')
@@ -79,44 +102,47 @@ export function useQrCode() {
localStorage.removeItem('scale')
}
function zoomIn() {
const canvas = qrCanvasRef.value
if (!canvas) {
logMessage('До генерации QR кода маштаб менять нельзя')
return
}
localStorage.setItem('scale', scale.value)
const canvasWidth = canvas.getBoundingClientRect().width
if (canvasWidth + 0.1 < window.innerWidth * 0.8) {
scale.value += 0.1
applyScale()
} else {
logMessage('Достигнут максимальный размер QR кода')
}
function closeQrModal() {
hasQr.value = false
}
function zoomOut() {
const canvas = qrCanvasRef.value
if (!canvas) {
async function zoomIn() {
if (!qrFrameRef.value || !textInput.value.trim()) {
logMessage('До генерации QR кода маштаб менять нельзя')
return
}
localStorage.setItem('scale', scale.value)
const canvasWidth = canvas.getBoundingClientRect().width
const previousScale = scale.value
scale.value += SCALE_STEP
await renderQrCanvas()
await nextTick()
if (canvasWidth > window.innerWidth * 0.8) {
scale.value = 1
if (getFrameWidth() > getMaxWidth()) {
scale.value = previousScale
await renderQrCanvas()
logMessage('Достигнут максимальный размер QR кода')
return
}
if (scale.value > 0.5) {
scale.value -= 0.1
applyScale()
} else {
persistScale()
logMessage('')
}
async function zoomOut() {
if (!qrFrameRef.value || !textInput.value.trim()) {
logMessage('До генерации QR кода маштаб менять нельзя')
return
}
if (scale.value <= MIN_SCALE) {
logMessage('Достигнут минимальный размер QR кода')
return
}
scale.value -= SCALE_STEP
await renderQrCanvas()
persistScale()
logMessage('')
}
async function restoreFromStorage() {
@@ -136,12 +162,13 @@ export function useQrCode() {
textInput,
error,
errorColor,
scale,
hasQr,
qrCanvasRef,
qrFrameRef,
generateQR,
downloadQR,
clearQR,
closeQrModal,
zoomIn,
zoomOut,
restoreFromStorage,