feat(tunnel): 优化隧道区域热点功能

- 重构了 SVG 图层和热区生成逻辑,支持动态渲染多个区域
- 添加了鼠标悬停和点击事件处理,优化了用户交互体验
- 优化了坐标转换函数,提高了热区精度
- 调整了样式和布局,提升了整体视觉效果
This commit is contained in:
dj
2025-09-16 23:05:08 +08:00
parent feddf9d1e5
commit 8220ca9f41

View File

@@ -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)"
/>
</svg>
@@ -54,7 +54,7 @@
<map name="image" id="image">
<area shape="poly" v-for="(item,index) in coordsList" :coords="item.coords" :key="index" alt=""
:id="'area'+index"
:title="item.title" style="cursor: pointer;pointer-events: none">
:title="item.title" style="cursor: pointer;pointer-events: none;">
<!-- :href="'/' + item.tunnelId + '/' + siteId" @click="clickHot(item.tunnelId,item.clickIndex)"-->
</map>
</div>
@@ -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(',');