canvas 实现渲染热力图

<!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: 100,
          y: 100,
          value: 80,
        },
        {
          x: 140,
          y: 140,
          value: 50,
        },
        {
          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);
        };
        console.log(Date.now());
        // 像素着色
        let imageData = context.getImageData(0, 0, 800, 800);
        let data = imageData.data;
        let palette = new Palette(context);
        for (var i = 3; i < data.length; i += 4) {
          let alpha = data[i];
          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);
        console.log(Date.now());
      };
    </script>
  </body>
</html>

  

原文地址:https://www.cnblogs.com/huangguofeng/p/15475521.html