From 8220ca9f41e46ae8ce0ccf90c9e78bef7f0cc82c Mon Sep 17 00:00:00 2001 From: dj <1042039504@qq.com> Date: Tue, 16 Sep 2025 23:05:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(tunnel):=20=E4=BC=98=E5=8C=96=E9=9A=A7?= =?UTF-8?q?=E9=81=93=E5=8C=BA=E5=9F=9F=E7=83=AD=E7=82=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构了 SVG 图层和热区生成逻辑,支持动态渲染多个区域 - 添加了鼠标悬停和点击事件处理,优化了用户交互体验 - 优化了坐标转换函数,提高了热区精度 - 调整了样式和布局,提升了整体视觉效果 --- src/views/tunnel/polygon-demo.vue | 116 +++++++++++++++++++----------- 1 file changed, 76 insertions(+), 40 deletions(-) diff --git a/src/views/tunnel/polygon-demo.vue b/src/views/tunnel/polygon-demo.vue index 3ae1519..05b0006 100644 --- a/src/views/tunnel/polygon-demo.vue +++ b/src/views/tunnel/polygon-demo.vue @@ -28,7 +28,7 @@ fill="rgba(0,150,255,0.3)" stroke="#0077cc" stroke-width="2" - style="cursor: pointer; pointer-events: none" + style="cursor: pointer; pointer-events: none;" @click="clickHot(item.tunnelId, item.clickIndex, index)" /> @@ -54,7 +54,7 @@ + :title="item.title" style="cursor: pointer;pointer-events: none;"> @@ -482,49 +482,85 @@ onMounted(() => { const pts = [{x: 50, y: 50}, {x: 300, y: 80}]; const str = pts.map(p => `${p.x},${p.y}`).join(' '); // 修改mouseenter和mouseout事件处理,使用防抖和更精确的检测 +// nextTick(() => { +// const area1 = document.getElementById("area0"); +// +// // 添加防抖标志,避免频繁切换 +// let hoverTimeout = null; +// let isHovered = false; +// +// if (area1) { +// area1.addEventListener("mouseenter", e => { +// console.log("鼠标进入区域0", e.clientX, e.clientY); +// // 清除之前的定时器 +// if (hoverTimeout) { +// clearTimeout(hoverTimeout); +// } +// +// // 设置hover状态 +// isHovered = true; +// hoveredAreaIndex.value = 0; +// }); +// +// area1.addEventListener("mousemove", e => { +// // 鼠标在区域内移动时保持显示状态 +// if (!isHovered) { +// isHovered = true; +// hoveredAreaIndex.value = 0; +// } +// }); +// +// area1.addEventListener("mouseleave", e => { +// console.log("鼠标离开区域0", e.clientX, e.clientY); +// // 设置延迟隐藏,避免闪动 +// if (hoverTimeout) { +// clearTimeout(hoverTimeout); +// } +// +// hoverTimeout = setTimeout(() => { +// isHovered = false; +// hoveredAreaIndex.value = 0; +// }, 100); // 100ms延迟 +// }); +// } +// }); + nextTick(() => { - const area1 = document.getElementById("area0"); + // 为所有area元素添加事件监听 + setTimeout(() => { + const areas = document.querySelectorAll('map[name="image"] area'); - // 添加防抖标志,避免频繁切换 - let hoverTimeout = null; - let isHovered = false; + let hoverTimeout = null; + areas.forEach((area, index) => { + console.log('area, index', area, index) + // 添加防抖定时器 - if (area1) { - area1.addEventListener("mouseenter", e => { - console.log("鼠标进入区域0", e.clientX, e.clientY); - // 清除之前的定时器 - if (hoverTimeout) { - clearTimeout(hoverTimeout); - } + area.addEventListener("mouseenter", () => { + // 清除之前的定时器 + if (hoverTimeout) { + clearTimeout(hoverTimeout); + } - // 设置hover状态 - isHovered = true; - hoveredAreaIndex.value = 0; + // 设置当前悬停的区域索引 + hoveredAreaIndex.value = index; + }); + + area.addEventListener("mouseleave", () => { + // 设置延迟隐藏,避免闪动 + if (hoverTimeout) { + clearTimeout(hoverTimeout); + } + + hoverTimeout = setTimeout(() => { + // 只有当当前悬停的还是这个区域时才隐藏 + if (hoveredAreaIndex.value === index) { + hoveredAreaIndex.value = -1; + } + }, 150); // 150ms延迟 + }); }); - - area1.addEventListener("mousemove", e => { - // 鼠标在区域内移动时保持显示状态 - if (!isHovered) { - isHovered = true; - hoveredAreaIndex.value = 0; - } - }); - - area1.addEventListener("mouseleave", e => { - console.log("鼠标离开区域0", e.clientX, e.clientY); - // 设置延迟隐藏,避免闪动 - if (hoverTimeout) { - clearTimeout(hoverTimeout); - } - - hoverTimeout = setTimeout(() => { - isHovered = false; - hoveredAreaIndex.value = -1; - }, 100); // 100ms延迟 - }); - } -}); - + }, 100); +}) function convertCoordsToArray(coordsArray) { return coordsArray.map(point => `${point.x},${point.y}`).join(',');