From 56e5aad22f71fdac2aded36edf877c72b4da212a Mon Sep 17 00:00:00 2001 From: Zhukj <3262118957> Date: Fri, 17 Apr 2026 14:29:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=8F=A0=E5=8A=A0?= =?UTF-8?q?=E5=9B=BE=E5=B1=82=E7=BA=A7=E5=85=B3=E7=B3=BB=E4=B8=8E=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=A4=B1=E7=84=A6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- css/style.css | 7 ++++-- index.html | 4 +-- js/script.js | 70 +++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6d0b84c..a9810d3 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ 13. 顶部工具栏下方16px的位置,固定放置文本编辑器工具栏,加粗,斜体,字体颜色,字体,字号,可编辑文字样式 14. 字号逻辑调整,输入框字号只在自身原本字号上增减 15. 文本输入框添加辅助线,完善辅助线的吸附逻辑更加精准,辅助线颜色为红色 -16. +16. 顶部工具栏新增层叠图,可添加多张层叠图,单击选中状态可缩放删除自由移动位置,置于背景图之上,输入框与层叠图点击只能同时选中一个 diff --git a/css/style.css b/css/style.css index 2fcdb24..2ad4c6d 100644 --- a/css/style.css +++ b/css/style.css @@ -222,14 +222,15 @@ html, body { overflow: hidden; } -/* 层叠图层 - 位于背景图之上、文字之下 */ +/* 层叠图层 - 位于背景图之上、文字之下、提示文字之上 */ .overlay-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; - pointer-events: none; + pointer-events: auto; + z-index: 6; } .overlay-layer .overlay-image { @@ -282,11 +283,13 @@ html, body { width: 100%; height: 100%; pointer-events: none; + z-index: 7; } /* 输入框可交互 */ .preview-input-layer .text-input { pointer-events: auto; + z-index: 8; } /* 背景图 - 保持比例,可滑动调整位置 */ diff --git a/index.html b/index.html index f612664..e608ee1 100644 --- a/index.html +++ b/index.html @@ -48,8 +48,6 @@
- -
请点击上方「添加图片」按钮上传背景图
背景图 @@ -66,6 +64,8 @@
编号:
+ +
请点击上方「添加图片」按钮上传背景图
diff --git a/js/script.js b/js/script.js index 15bf2d5..8f98eed 100644 --- a/js/script.js +++ b/js/script.js @@ -405,23 +405,29 @@ }); } - // 选中层叠图 + // 选中层叠图(同时取消输入框选中) let selectedOverlay = null; function selectOverlay(overlayEl) { - if (selectedOverlay) { + if (selectedInput) { + selectedInput.classList.remove('selected'); + selectedInput = null; + } + if (editingInput) { + endEdit(editingInput); + } + if (selectedOverlay && selectedOverlay !== overlayEl) { selectedOverlay.classList.remove('selected'); } selectedOverlay = overlayEl; overlayEl.classList.add('selected'); } - // 点击背景取消选中层叠图 + // 点击背景/空白处取消选中层叠图 imageContainer.addEventListener('click', (e) => { - if (e.target === imageContainer || - e.target === bgLayer || - e.target === bgImage || - e.target === emptyTip || - e.target.closest('.preview-bg-layer')) { + const isOverlayImage = e.target.closest('.overlay-image'); + const isTextInput = e.target.closest('.text-input'); + + if (!isOverlayImage && !isTextInput) { if (selectedOverlay) { selectedOverlay.classList.remove('selected'); selectedOverlay = null; @@ -732,6 +738,10 @@ // 选中输入框 function selectInput(element) { + if (selectedOverlay) { + selectedOverlay.classList.remove('selected'); + selectedOverlay = null; + } if (editingInput && editingInput !== element) { endEdit(editingInput); } @@ -1404,6 +1414,9 @@ drawImageWithOffset(ctx, currentImage, containerWidth, containerHeight); } + // 绘制层叠图(等待图片加载完成) + await drawOverlayImages(ctx); + // 绘制文字 drawTextOnCanvas(ctx, input1); drawTextOnCanvas(ctx, input2); @@ -1411,6 +1424,47 @@ return canvas; } + // 绘制层叠图 + function drawOverlayImages(ctx) { + return new Promise((resolve) => { + const overlayImages = overlayLayer.querySelectorAll('.overlay-image'); + if (overlayImages.length === 0) { + resolve(); + return; + } + + let loadedCount = 0; + overlayImages.forEach(overlayEl => { + const imgEl = overlayEl.querySelector('img'); + if (!imgEl) { + loadedCount++; + return; + } + + const left = overlayEl.offsetLeft; + const top = overlayEl.offsetTop; + const width = overlayEl.offsetWidth; + const height = overlayEl.offsetHeight; + + const img = new Image(); + img.onload = () => { + ctx.drawImage(img, left, top, width, height); + loadedCount++; + if (loadedCount >= overlayImages.length) { + resolve(); + } + }; + img.onerror = () => { + loadedCount++; + if (loadedCount >= overlayImages.length) { + resolve(); + } + }; + img.src = imgEl.src; + }); + }); + } + // 绘制图片(考虑滑动偏移) function drawImageWithOffset(ctx, img, containerWidth, containerHeight) { const imgRatio = img.naturalWidth / img.naturalHeight;