diff --git a/src/components/tools/QrCode.vue b/src/components/tools/QrCode.vue index 8547cfa..73b2660 100644 --- a/src/components/tools/QrCode.vue +++ b/src/components/tools/QrCode.vue @@ -17,12 +17,53 @@ const isBgTransparent = useLocalStorage('isBgTransparent', true, 'qr-code') const bgType = useLocalStorage('bgType', 'solid', 'qr-code') const bgColor1 = useLocalStorage('bgColor1', '#ffffff', 'qr-code') const bgColor2 = useLocalStorage('bgColor2', '#e2e8f0', 'qr-code') +const bgGradPos = useLocalStorage('bgGradPos', { x1: 50, y1: 50, x2: 100, y2: 100 }, 'qr-code') const fgType = useLocalStorage('fgType', 'solid', 'qr-code') const fgColor1 = useLocalStorage('fgColor1', '#000000', 'qr-code') const fgColor2 = useLocalStorage('fgColor2', '#10b981', 'qr-code') +const fgGradPos = useLocalStorage('fgGradPos', { x1: 0, y1: 0, x2: 100, y2: 100 }, 'qr-code') const svgContent = ref('') const previewRef = ref(null) +const qrFrameRef = ref(null) + +const activeHandle = ref(null) + +const startDrag = (e, handleStr) => { + e.preventDefault() + activeHandle.value = handleStr + window.addEventListener('mousemove', onDrag) + window.addEventListener('mouseup', stopDrag) + window.addEventListener('touchmove', onDrag, { passive: false }) + window.addEventListener('touchend', stopDrag) +} + +const onDrag = (e) => { + if (!activeHandle.value || !qrFrameRef.value) return + if (e.type === 'touchmove') e.preventDefault() + + const rect = qrFrameRef.value.getBoundingClientRect() + const clientX = e.touches ? e.touches[0].clientX : e.clientX + const clientY = e.touches ? e.touches[0].clientY : e.clientY + + let x = ((clientX - rect.left) / rect.width) * 100 + let y = ((clientY - rect.top) / rect.height) * 100 + x = Math.max(0, Math.min(100, x)) + y = Math.max(0, Math.min(100, y)) + + const [type, point] = activeHandle.value.split(':') + const posRef = type === 'fg' ? fgGradPos : bgGradPos + posRef.value[`x${point}`] = Math.round(x) + posRef.value[`y${point}`] = Math.round(y) +} + +const stopDrag = () => { + activeHandle.value = null + window.removeEventListener('mousemove', onDrag) + window.removeEventListener('mouseup', stopDrag) + window.removeEventListener('touchmove', onDrag) + window.removeEventListener('touchend', stopDrag) +} const { height: previewHeight } = useFillHeight(previewRef, 40) // 40px extra margin @@ -64,15 +105,17 @@ const generateQR = () => { bgType: bgType.value, bgColor1: bgColor1.value, bgColor2: bgColor2.value, + bgGradPos: { ...bgGradPos.value }, fgType: fgType.value, fgColor1: fgColor1.value, - fgColor2: fgColor2.value + fgColor2: fgColor2.value, + fgGradPos: { ...fgGradPos.value } }) } -watch([text, ecc, isBgTransparent, bgType, bgColor1, bgColor2, fgType, fgColor1, fgColor2], () => { +watch([text, ecc, isBgTransparent, bgType, bgColor1, bgColor2, bgGradPos, fgType, fgColor1, fgColor2, fgGradPos], () => { generateQR() -}) +}, { deep: true }) watch(text, (newText) => { if (newText) { @@ -234,7 +277,25 @@ const triggerDownload = (blob, filename) => {