实际效果图
本文借鉴与腾讯位置服务的一位前端工程师写的代码,不得不佩服鹅厂的人才很牛,于是就借鉴一下,不过不知是我对于人家的代码理解不太透彻,还是别的原因,下面的代码运行的很慢,要很久才能将热力图展示出来,里面重点为的构造函数和Canvas画图
主要借鉴这个网站[腾讯大神热力图]https://mp.weixin.qq.com/s/PAEj8Pie5O6RrOmezocpWw
还有这个热力图解释
如果看到的朋友觉得我的代码哪里有问题,还请指出来,谢谢,因为效果一直不好
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hotmap</title>
</head>
<body>
<canvas id="hotmap" width="800" height="800" style="border:1px solid #000000;"></canvas>
<script>
var pointsdata = [{
x: 471,
y: 277,
value: 25
}, {
x: 438,
y: 375,
value: 97
}, {
x: 373,
y: 19,
value: 71
}, {
x: 473,
y: 42,
value: 63
}, {
x: 463,
y: 95,
value: 97
}, {
x: 590,
y: 437,
value: 34
}, {
x: 377,
y: 442,
value: 66
}, {
x: 171,
y: 254,
value: 20
}, {
x: 6,
y: 582,
value: 64
}, {
x: 387,
y: 477,
value: 14
}, {
x: 300,
y: 300,
value: 80
}];
window.onload = function() {
var canvas = document.getElementById('hotmap');
if (canvas.getContext) {
var context = canvas.getContext("2d");
} else {
alert('浏览器不支持canvas!');
}
context.clearRect(0, 0, 800, 800);
/*
* radius: 绘制半径,请自行设置
* min, max: 强弱阈值,可自行设置,也可取数据最小最大值
*/
var radius = 50;
var max = 97;
var min = 14;
pointsdata.forEach(point => {
let {
x,
y,
value
} = point;
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI);
context.closePath();
// 创建渐变色: r,g,b取值比较自由,我们只关注alpha的数值
let radialGradient = context.createRadialGradient(x, y, 0, x, y, radius);
radialGradient.addColorStop(0.0, "rgba(0,0,0,1)");
radialGradient.addColorStop(1.0, "rgba(0,0,0,0)");
context.fillStyle = radialGradient;
// 设置globalAlpha: 需注意取值需规范在0-1之间
let globalAlpha = (value - min) / (max - min);
context.globalAlpha = Math.max(Math.min(globalAlpha, 1), 0);
// 填充颜色
context.fill();
});
const defaultColorStops = {
0: "#0ff",
0.2: "#0f0",
0.4: "#ff0",
1: "#f00",
};
const width = 20,
height = 256;
function Palette(opts) {
Object.assign(this, opts);
this.init();
}
Palette.prototype.init = function() {
let colorStops = this.colorStops || defaultColorStops;
// 创建canvas
let canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext("2d");
// 创建线性渐变色
let linearGradient = ctx.createLinearGradient(0, 0, 0, height);
for (const key in colorStops) {
linearGradient.addColorStop(key, colorStops[key]);
}
// 绘制渐变色条
ctx.fillStyle = linearGradient;
ctx.fillRect(0, 0, width, height);
// 读取像素数据
this.imageData = ctx.getImageData(0, 0, 1, height).data;
this.canvas = canvas;
};
/**
* 取色器
* @param {Number} position 像素位置
* @return {Array.<Number>} [r, g, b]
*/
Palette.prototype.colorPicker = function(position) {
return this.imageData.slice(position * 4, position * 4 + 3);
};
// 像素着色
let imageData = context.getImageData(0, 0, 800, 800);
let data = imageData.data;
for (var i = 3; i < data.length; i += 4) {
let alpha = data[i];
let palette = new Palette(this.context)
let color = palette.colorPicker(alpha);
data[i - 3] = color[0];
data[i - 2] = color[1];
data[i - 1] = color[2];
}
context.putImageData(imageData, 0, 0);
}
</script>
</body>
</html>
更多前端资料
请关注公众号:前端从入门到SP