容器中使用图片地图全覆盖
JSON文件加载,各个点位相对图片容器位置创建可点击点位,可点击点位扩大10px创建点击事件(直接用css标签 然后来实现),调用模态框,可以添加AJAX事件实现交互。
循环上面步骤 大地图嵌套模态框显示小地图,或者显示点击交互事件,小地图也可以在上面创建交互实现地图的联合交互创建。
地图的相对点位如何创建?
下面列子非常好显示 了其中内容,创建一个图片容器div,1920×1080 大小,不可缩放。
图片100%铺满,通过each 以及定义好的css 创建点击位置,和方法
区域定位.css({left:item.x,top:item.y})
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<style>
.map-box{
position:relative;
width:1920px;
height:1080px;
border:1px solid #999;
}
.factory-map{
width:1920px;
height:1080px;
display:block;
}
body{
overflow:auto;
}
/* 热区:宽高32px,四周多出10px点击范围 用于创建点击事件 巧妙*/
.point-hot{
position:absolute;
width:32px;
height:32px;
transform:translate(-50%,-50%);
cursor:pointer;
background:transparent;
}
.point-dot{
width:12px;
height:12px;
background:#f33;
border-radius:50%;
margin:10px;
}
.point-text{
position:absolute;
margin-top:-18px;
font-size:12px;
white-space:nowrap;
}
</style>
</head>
<body>
<div class="map-box" id="mapBox">
<img class="factory-map" src="factory.jpg">
</div>
<script>
$(function(){
let pointList = [
{x:300,y:220,name:"一号车间"},
{x:650,y:480,name:"水泵房"}
];
const $mapBox = $("#mapBox");
$.each(pointList,function(i,item){
let $hot = $("<div class='point-hot'></div>")
.css({left:item.x,top:item.y})
.append("<div class='point-dot'></div><div class='point-text'>"+item.name+"</div>");
// 点击热区任意位置,弹出点位名称
$hot.click(function(e){
e.stopPropagation();
alert(item.name);
});
$mapBox.append($hot);
})
// 空白区域点击只打印坐标,不弹窗
$mapBox.click(function(e){
let r = $mapBox[0].getBoundingClientRect();
let x = e.clientX - r.left,y = e.clientY - r.top;
console.log("X:"+parseInt(x)+" Y:"+parseInt(y));
})
})
</script>
</body>
</html>
创建区域
通过CSS来确定显示的样式
#CSS
/* 全局热力覆盖图层,底层、鼠标穿透不干扰点击 */
.heat-layer{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
z-index:2; /* 固定在厂房下方,底图上方 */
pointer-events:none; /* 关键:色块不拦截鼠标点击厂房/传感器 */
display:none;
}
/* 单块厂房热力色块 */
.heat-block{
position:absolute;
filter: blur(12px); /* 色块之间柔和渐变融合 */
border-radius:6px;
}
创建区域 【显示区域使用添加DIV中加入上面的CSS样式,后用js读取json厂区的宽高后设置宽高 】区域定位参考上面,宽高定位width high
// 循环所有分区
parkConfig.zones.forEach((zone,zoneIdx)=>{
// 循环当前分区全部厂房
zone.factories.forEach((fac,facIdx)=>{
// 厂房矩形宽高、坐标
const tw = fac.x2 - fac.x1;
const th = fac.y2 - fac.y1;
// 根据业务温度获取厂房对应颜色
function getTempColor(temp){
if(temp<20)return "#2196F3";
else if(temp>30)return "#f44336";
return "#4CAF50";
}
// 这里简化统一厂房底色,你可替换为区域平均温度色
const areaColor = "#0066ff";
// 创建厂房热力覆盖色块,放入独立热力图层
let $heat = $(`<div class="heat-block"></div>`)
.css({
left: fac.x1,
top: fac.y1,
width: tw,
height: th,
background: areaColor,
opacity: 0.28 // 透明度,不遮挡底图
})
// 追加到热力覆盖图层
$heatLayer.append($heat);
})
})
点击事件及点击后触发
使用AJAX去后台读取内容,使用模态框来显示回传信息,可以在其内部添加一个请求的url【包含请求信息】通过GET请求回传JSON信息。
实时点位显示
同步动态点位信息,比如巡检ID显示,直接定期AJAX请求,然后显示点,可以在顶部显示z-index,数值高。依然适用ajax点击事件显示。(也可以直接展示信息)
跟正点击信息
A 直接URL 通过AJAX后请求后模态框展示信息
B 直接展示信息,直接模态框展示信息
doing中JSON显示其中 有url和 info两个参数分别去读取。
热力图
一、CSS 部分(分 3 块:画布基础、热力容器、圆形热力块)
1. 画布基础容器(固定 1900×900,承载底图 + 所有图层)
css
.map-wrap{
position:relative;
width:1900px;
height:900px;
border:2px solid #666;
overflow:auto;
}
#bgImg{
position:absolute;
left:0;top:0;
width:1900px;height:900px;
object-fit:cover;
display:block;
}
作用:
- 固定画布尺寸 1900 宽 900 高,所有坐标基于这个画布;
position:relative 给内部热力、厂房、点位提供定位基准。
2. 热力总容器 .heat-layer(整层统一控制)
css
.heat-layer{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
z-index:2; /* 层级:底图之上、厂房之下 */
pointer-events:none; /* 核心:鼠标穿透,不挡住点击厂房/传感器 */
display:none; /* 默认隐藏,开关按钮控制显示 */
}
关键属性解释:
position:absolute:铺满整个画布;
z-index:2 图层顺序:底图 (0) < 热力层 (2) < 厂房 (4) < 传感器 (8);
pointer-events:none:鼠标操作会直接穿过热力色块,底层交互完全不受影响;
display:none:一键开关只改这个容器的 display,不用删所有色块。
3. 单个圆形热力块 .heat-block(核心实现圆形 + 渐变融合)
css
.heat-block{
position:absolute;
border-radius:50%; /* 强制正方形div变成正圆形 */
filter: blur(20px); /* 高斯模糊,让圆形边缘向外虚化,多个圆融合渐变 */
}
两条核心:
border-radius:50%:宽高相等的 div,圆角 50% = 标准圆形;
filter: blur(20px):圆形边缘向外扩散虚化 20 像素,相邻圆形色块重叠后自动形成平滑过渡,这就是你看到整片渐变的来源;
- 如果去掉
blur(20px),就能清晰看到一个个独立圆形热源。
二、JS 分步拆解(只看热力相关逻辑,分 5 步)
前置说明
数据结构:parkConfig.zones[0].sensors 是独立传感器数组,每个传感器包含 x,y,temp,热源只来源于这些点位。
步骤 1:工具函数 —— 根据温度返回热力颜色
js
运行
// 输入温度,返回半透明RGBA颜色
function tempToHeatColor(temp){
if(temp <= 20) return "rgba(33,150,243,0.28)"; // 低温蓝色
if(temp <= 30) return "rgba(76,175,80,0.28)"; // 常温绿色
return "rgba(244,67,54,0.28)"; // 高温红色
}
末尾 0.28 = 色块透明度,数值越低底色越淡,能看清底下厂区底图。
步骤 2:热力渲染主函数 renderHeatMap()(循环生成所有圆形色块)
js
运行
function renderHeatMap(){
// 第一步:清空上一轮所有热力圆形,防止重复叠加
$(".heat-block").remove();
const $heatLayer = $("#heatLayer");
// 遍历所有园区分区(当前只有1个默认分区)
parkConfig.zones.forEach(zone=>{
// 遍历【独立传感器数组】,每一个传感器生成1个圆形热力块
zone.sensors.forEach(sen=>{
// 1.获取当前传感器对应的温度颜色
const fillColor = tempToHeatColor(sen.temp);
// 2.根据温度计算圆形扩散半径:温度越高,圆越大
const spreadRadius = Math.max(40, Math.min(130, sen.temp * 2.3));
// Math.max(40,xxx):最小半径40,不会过小看不见
// Math.min(130,xxx):最大半径130,不会铺满整张图
// 3.创建圆形DOM热力块,定位到传感器坐标中心
$("<div class='heat-block'></div>")
.css({
// 圆心在sen.x sen.y,向左/上偏移半径,保证圆形中心对准传感器点位
left: sen.x - spreadRadius,
top: sen.y - spreadRadius,
// 宽高 = 两倍半径,形成完整圆形
width: spreadRadius * 2,
height: spreadRadius * 2,
background: fillColor
})
// 把圆形色块追加到热力总容器内
.appendTo($heatLayer);
})
})
}
坐标逻辑重点
- 传感器坐标
sen.x sen.y 是圆形圆心;
- 圆形宽高
2*spreadRadius;
left = 圆心x - 半径、top = 圆心y - 半径,才能让圆形中心精准落在传感器绿点上。
步骤 3:全局渲染入口,每次重绘自动刷新热力
js
运行
function renderAll(){
clearRender(); // 清空厂房、点位、旧热力
// 渲染分区、厂房、传感器红点(原有逻辑省略)
renderHeatMap(); // 最后执行热力圆形生成,刷新整张温度图层
}
触发时机:新建 / 删除传感器、导入 JSON、修改温度后,执行 renderAll(),热力自动重新绘制。
步骤 4:热力图层开关按钮逻辑(控制整层显示隐藏)
js
运行
let heatShow = false;
$("#toggleHeat").click(function(){
heatShow = !heatShow;
// 只修改热力总容器display,所有圆形色块一起显示/隐藏
$heatLayer.css("display", heatShow ? "block" : "none");
$(this).text(heatShow ? "关闭温度热力图层" : "开启温度热力图层");
})
不用逐个删除圆形 DOM,只控制外层容器,性能更高。
步骤 5:补充:关闭模糊,看清原生圆形(可选按钮逻辑)
新增变量控制模糊,切换后能清晰看到单个圆形:
js
运行
let heatBlurOn = true;
$("#toggleBlur").click(function(){
heatBlurOn = !heatBlurOn;
renderAll();
})
// 修改renderHeatMap内css赋值,动态控制blur
let cssStyle = {
left: sen.x - spreadRadius,
top: sen.y - spreadRadius,
width: spreadRadius * 2,
height: spreadRadius * 2,
background: fillColor
};
if(heatBlurOn){
cssStyle.filter = "blur(20px)";
}
$("<div class='heat-block'></div>").css(cssStyle).appendTo($heatLayer);
heatBlurOn=true:开启模糊,圆形边缘融合,看不出单独圆形;
heatBlurOn=false:无模糊,每个热源都是清晰独立圆形。
三、完整运行逻辑流程(从头到尾执行顺序)
- 上传厂区图片,填充
#bgImg 作为画布底图;
- 用户点击「绘制传感器点位」,在画布点击生成传感器,存入
zone.sensors;
- 点击「开关热力图层」,
heatShow=true,.heat-layer 变为 display:block;
- 页面执行
renderAll() → 调用 renderHeatMap();
- JS 循环读取所有独立传感器
x/y/temp;
- 根据温度计算圆形半径、半透明颜色;
- 批量创建带
border-radius:50% 的圆形 div,放入热力容器;
- CSS
blur(20px) 虚化所有圆形边缘,色块互相叠加融合,形成整张平滑温度图层;
- 热力层
pointer-events:none,底层厂房、传感器删除、弹窗功能完全不受遮挡。
四、你疑惑 “看不到圆形” 的根本原因
- 每个热源确实是标准圆形 div;
- 代码默认开启
filter: blur(20px),圆形边缘向外大面积虚化扩散;
- 多个圆形虚化区域重叠、颜色混合,肉眼看不到单独圆形轮廓,只看到整片渐变;
- 关闭 blur 模糊后,立刻能看到一个个独立圆形热源。