style(qr): enhance editable gradient handles with a glow and add visibility toggle

This commit is contained in:
2026-03-04 03:24:53 +00:00
parent 8fa0c9bd44
commit 805b986a7b

View File

@@ -22,6 +22,7 @@ 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 showHandles = useLocalStorage('showHandles', true, 'qr-code')
const svgContent = ref('')
const previewRef = ref(null)
@@ -281,24 +282,32 @@ const triggerDownload = (blob, filename) => {
<div class="svg-wrapper" ref="qrFrameRef">
<div v-html="svgContent" class="svg-content-box"></div>
<!-- Background Gradient Handles -->
<template v-if="!isBgTransparent && bgType !== 'solid'">
<svg class="grad-line-svg"><line :x1="bgGradPos.x1 + '%'" :y1="bgGradPos.y1 + '%'" :x2="bgGradPos.x2 + '%'" :y2="bgGradPos.y2 + '%'" class="bg-line" /></svg>
<div class="grad-handle bg-handle handle-1" :style="{ left: bgGradPos.x1 + '%', top: bgGradPos.y1 + '%' }" @mousedown="startDrag($event, 'bg:1')" @touchstart.prevent="startDrag($event, 'bg:1')"></div>
<div class="grad-handle bg-handle handle-2" :style="{ left: bgGradPos.x2 + '%', top: bgGradPos.y2 + '%' }" @mousedown="startDrag($event, 'bg:2')" @touchstart.prevent="startDrag($event, 'bg:2')"></div>
</template>
<template v-if="showHandles">
<!-- Background Gradient Handles -->
<template v-if="!isBgTransparent && bgType !== 'solid'">
<svg class="grad-line-svg"><line :x1="bgGradPos.x1 + '%'" :y1="bgGradPos.y1 + '%'" :x2="bgGradPos.x2 + '%'" :y2="bgGradPos.y2 + '%'" class="bg-line" /></svg>
<div class="grad-handle bg-handle handle-1" :style="{ left: bgGradPos.x1 + '%', top: bgGradPos.y1 + '%' }" @mousedown="startDrag($event, 'bg:1')" @touchstart.prevent="startDrag($event, 'bg:1')"></div>
<div class="grad-handle bg-handle handle-2" :style="{ left: bgGradPos.x2 + '%', top: bgGradPos.y2 + '%' }" @mousedown="startDrag($event, 'bg:2')" @touchstart.prevent="startDrag($event, 'bg:2')"></div>
</template>
<!-- Foreground Gradient Handles -->
<template v-if="fgType !== 'solid'">
<svg class="grad-line-svg"><line :x1="fgGradPos.x1 + '%'" :y1="fgGradPos.y1 + '%'" :x2="fgGradPos.x2 + '%'" :y2="fgGradPos.y2 + '%'" class="fg-line" /></svg>
<div class="grad-handle fg-handle handle-1" :style="{ left: fgGradPos.x1 + '%', top: fgGradPos.y1 + '%' }" @mousedown="startDrag($event, 'fg:1')" @touchstart.prevent="startDrag($event, 'fg:1')"></div>
<div class="grad-handle fg-handle handle-2" :style="{ left: fgGradPos.x2 + '%', top: fgGradPos.y2 + '%' }" @mousedown="startDrag($event, 'fg:2')" @touchstart.prevent="startDrag($event, 'fg:2')"></div>
<!-- Foreground Gradient Handles -->
<template v-if="fgType !== 'solid'">
<svg class="grad-line-svg"><line :x1="fgGradPos.x1 + '%'" :y1="fgGradPos.y1 + '%'" :x2="fgGradPos.x2 + '%'" :y2="fgGradPos.y2 + '%'" class="fg-line" /></svg>
<div class="grad-handle fg-handle handle-1" :style="{ left: fgGradPos.x1 + '%', top: fgGradPos.y1 + '%' }" @mousedown="startDrag($event, 'fg:1')" @touchstart.prevent="startDrag($event, 'fg:1')"></div>
<div class="grad-handle fg-handle handle-2" :style="{ left: fgGradPos.x2 + '%', top: fgGradPos.y2 + '%' }" @mousedown="startDrag($event, 'fg:2')" @touchstart.prevent="startDrag($event, 'fg:2')"></div>
</template>
</template>
</div>
</div>
</div>
<div class="download-settings">
<div class="control-group" v-if="fgType !== 'solid' || (!isBgTransparent && bgType !== 'solid')">
<label class="checkbox-label">
<input type="checkbox" v-model="showHandles"> Show edit handles
</label>
</div>
<div class="control-group">
<label>Size (px)</label>
<div class="number-control size-control">
@@ -482,13 +491,15 @@ const triggerDownload = (blob, filename) => {
.grad-handle {
position: absolute;
width: 20px;
height: 20px;
width: 14px;
height: 14px;
transform: translate(-50%, -50%);
border-radius: 50%;
cursor: grab;
z-index: 10;
touch-action: none;
background: var(--text-strong);
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8), 0 0 8px 2px rgba(255, 255, 255, 0.6);
}
.grad-handle:active {
@@ -496,27 +507,25 @@ const triggerDownload = (blob, filename) => {
}
.fg-handle {
border: 2px solid var(--primary-accent);
background: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
background: var(--text-strong);
}
.bg-handle {
border: 2px dotted #888;
background: rgba(255,255,255,0.9);
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
background: var(--text-secondary);
}
.fg-line {
stroke: var(--primary-accent);
stroke-width: 2;
stroke: var(--text-strong);
stroke-width: 1.5;
stroke-dasharray: 4;
filter: drop-shadow(0px 0px 2px rgba(255,255,255,1));
}
.bg-line {
stroke: #888;
stroke-width: 2;
stroke: var(--text-secondary);
stroke-width: 1.5;
stroke-dasharray: 2;
filter: drop-shadow(0px 0px 2px rgba(255,255,255,1));
}
.download-settings {