vue 项目中画热力图

<template>
  <div>
    <canvas :width="widthPal" :height="heightPal" id="canvas_01"></canvas>
    <canvas
      :width="widthImg"
      :height="heightImg"
      id="canvas_02"
      style="background-color: #fff; margin-left: 20px"
    ></canvas>
  </div>
</template>
<script>
export default {
  data () {
    return {
      data: [
        { 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 },
        { x: 40, y: 40, value: 18 },
        { x: 80, y: 40, value: 19 },
      ],
      defaultColorStops: {
        0: "#0ff",
        0.2: "#0f0",
        0.4: "#ff0",
        1: "#f00",
      },
      // 图例
      widthPal: 20,
      heightPal: 256,
      // 热力图范围
      widthImg: 600,
      heightImg: 600,
      radius: 40, // 径向渐变半径
      // 热力图代表的最大最小值
      max: 10,
      min: 5,
      imageData: null,
      alpha: null
    }
  },
  mounted () {
    this.init();
    this.draw();
  },
  methods: {
    init () {
      const colorStops = this.defaultColorStops;
      // 创建canvas
      const canvas = document.getElementById("canvas_01");
      const ctx = canvas.getContext("2d");

      // 创建线性渐变色
      const linearGradient = ctx.createLinearGradient(0, 0, 0, this.heightPal);
      for (const key in colorStops) {
        linearGradient.addColorStop(key, colorStops[key]);
      }

      // 绘制渐变色条
      ctx.fillStyle = linearGradient;
      ctx.fillRect(0, 0, this.widthPal, this.heightPal);

      // 读取像素数据
      this.imageData = ctx.getImageData(0, 0, 1, this.heightPal).data;
      this.canvas = canvas;
    },
    /**
 * 取色器
 * @param {Number} position 像素位置
 * @return {Array.<Number>} [r, g, b]
 */
    colorPicker (position) {
      return this.imageData.slice(position * 4, position * 4 + 3);
    },
    draw () {
      const radius = this.radius
      const max = this.max
      const min = this.min
      const canvas = document.getElementById("canvas_02");
      // canvas.width = this.width;
      // canvas.height = this.height;
      const context = canvas.getContext("2d");
      this.data.forEach(point => {
        const { x, y, value } = point;
        context.beginPath();
        context.arc(x, y, radius, 0, 2 * Math.PI);
        context.closePath();

        // 创建渐变色: r,g,b取值比较自由,我们只关注alpha的数值
        const 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之间
        const globalAlpha = (value - min) / (max - min);
        context.globalAlpha = Math.max(Math.min(globalAlpha, 1), 0);
        // 填充颜色
        context.fill();
        // 像素着色
        // tips:  ImageData 对象中每一个像素
        // red = imgData.data[0];
        // green = imgData.data[1];
        // blue = imgData.data[2];
        // alpha = imgData.data[3];
        const imageData = context.getImageData(0, 0, this.widthImg, this.heightImg);
        const data = imageData.data;
        for (var i = 3; i < data.length; i += 4) {
          const alpha = data[i];
          const color = this.colorPicker(alpha);
          data[i - 3] = color[0];
          data[i - 2] = color[1];
          data[i - 1] = color[2];
        }
        context.putImageData(imageData, 0, 0);
      });
    }
  }
}
</script>

参考 https://mp.weixin.qq.com/s/bgS7uFlyLtK8WtusKfv8lA

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值