Canvas热力图绘制核心是数据强度到颜色的精准映射:需统一坐标转像素、灰度叠加密度计算、可配置颜色梯度及动态帧控优化。

Canvas绘制热力图的核心在于把数据强度合理转为视觉颜色,关键不在“画得多”,而在“映射得准”——像素位置决定数据落点,颜色梯度决定强度表达。
坐标到像素的准确映射
原始数据(如经纬度、页面坐标或网格索引)必须统一转换为Canvas内的整数像素坐标,否则会出现模糊、偏移或采样错位。
- 地图场景:用墨卡托投影等地理坐标系工具,将{lng, lat}转为{x, y}像素,注意缩放级别影响精度,需动态重算
- 网页行为分析:直接取event.clientX/clientY,减去canvas.getBoundingClientRect().left/top,再乘devicePixelRatio适配高清屏
- 网格数据(如10×12风速阵列):按比例缩放,x = colIndex × (canvas.width / colCount),y = rowIndex × (canvas.height / rowCount),避免四舍五入导致空行/空列
灰度叠加是密度计算的基础
热力图本质是空间密度分布,单个点不是实心圆,而是带衰减的径向影响场。推荐用离屏Canvas预绘灰度渐变核,再批量合成:
- 创建1px黑点+createRadialGradient:圆心alpha=1,边缘alpha=0,半径建议设为15–30px(依数据密度调整)
- 每个数据点按value缩放globalAlpha,例如alpha = (value - min) / (max - min),保证小值不被淹没、大值不溢出
- 所有点绘制到一个隐藏的Uint8ClampedArray灰度缓冲区(非直接画布),用整数运算累加,比反复getImageData更高效
颜色梯度要可配置、可插值
固定三色(蓝→黄→红)不够灵活,真实业务常需自定义断点与透明度。推荐用线性插值查表法:
- 定义色卡数组:[[0,0,255,128], [0,255,255,192], [255,255,0,224], [255,0,0,255]],每个子项为[r,g,b,a]
- 归一化灰度值v ∈ [0, 1],定位在第i段(如v=0.67落在第2→3段),再按比例混合两端颜色
- alpha值建议随强度上升而增强(如0.3→1.0),避免低值区域完全不可见
动态更新要控制帧负载
实时热力图易卡顿,关键是减少每帧重绘量:
- 用requestAnimationFrame驱动,禁用setInterval
- 每帧仅清空部分画布(如ctx.fillStyle = 'rgba(0,0,0,0.03)'; ctx.fillRect(0,0,w,h)),实现自然淡出拖尾
- 新数据只更新受影响的局部像素块,旧数据用时间衰减因子(如e⁻ᵗ)降低权重,而非全量重建

















