小程序中canvas的问题参考

参考文档: https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html

小程序中canvas的问题参考

 

 

const numCount = 3; // 元素个数
const numSlot = 4; // 一条线上的总节点数
const mW = 340; // Canvas的宽度
const mCenter = mW / 2; // 中心点
const mAngle = (Math.PI * 2) / numCount; // 角度
const mRadius = mCenter - 80; // 半径(减去的值用于给绘制的文本留空间)
// 获取指定的Canvas
let radCtx = null;

  

  // 获取canvas 节点
  getNodecanvas(valuedata) {
    radCtx = wx.createCanvasContext(‘radarCanvas‘, this(子组件中添加));
    this.drawRadar(valuedata);
  },

  

  // 雷达图
  drawRadar(valdata) {
    // console.log(valdata)
    // 调用
    this.drawArcEdge(); // 画圆
    this.drawLinePoint();
    // 设置数据
    this.drawRegion(valdata, ‘rgba(101, 163, 243, 1)‘);
    // 设置文本数据
    this.drawTextCans(valdata);
    // 设置节点
    this.drawCircle(valdata, ‘#267EF0‘);
    radCtx.draw(true, this.saveCanvasImage);
  },
  // / 第一步:绘制5个圆,可以通过修改numSlot的数的大小,来确定绘制几个圆
  drawArcEdge() {
    // radCtx.strokeStyle = "#E0E2E9"
    // radCtx.lineWidth = 1  //设置线宽
    radCtx.setStrokeStyle(‘#E0E2E9‘);
    radCtx.setLineWidth(1); // 设置线宽
    for (let i = 0; i < numSlot; i++) {
      // 计算半径
      radCtx.beginPath();
      const rdius = (mRadius / numSlot) * (i + 1); // 计算每个圆的半径
      // 画6条线段
      for (let j = 0; j < numSlot; j++) {
        // 计算半径
        radCtx.beginPath();
        radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI); // 开始画圆
        // radCtx.stroke()
      }
      radCtx.closePath();
      radCtx.stroke();
    }
  },

  // 绘制连接点
  drawLinePoint() {
    radCtx.setLineDash([5, 10], 2);
    radCtx.beginPath();
    for (let k = 0; k < numCount; k++) {
      const x = mCenter + mRadius * Math.cos(mAngle * k);
      const y = mCenter + mRadius * Math.sin(mAngle * k);

      radCtx.moveTo(mCenter, mCenter);
      radCtx.lineTo(x, y);
    }
    radCtx.stroke();
  },
  // 绘制数据区域(数据和填充颜色)
  drawRegion(mData, color) {
    radCtx.beginPath();
    for (let m = 0; m < numCount; m++) {
      const x = mCenter + (mRadius * Math.cos(mAngle * m)) * (mData[m][1] / 100);
      const y = mCenter + (mRadius * Math.sin(mAngle * m)) * (mData[m][1] / 100);

      radCtx.lineTo(x, y);
    }
    radCtx.closePath();
    radCtx.fillStyle = color;
    radCtx.fill();
  },

  // 绘制文字
  drawTextCans(mData) {
    // radCtx.fillStyle = "#9B9B9B"
    radCtx.setFillStyle(‘#9B9B9B‘);
    radCtx.font = ‘bold 15px cursive‘; // 设置字体
    for (let n = 0; n < numCount; n++) {
      const x = mCenter + mRadius * Math.cos(mAngle * n);
      const y = mCenter + mRadius * Math.sin(mAngle * n);
      // radCtx.fillText(mData[n][0], x, y);
      // 通过不同的位置,调整文本的显示位置
      if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) {
        radCtx.fillText(mData[n][0], x + 5, y + 5);
      } else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) {
        radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width - 7, y + 5);
      } else if (mAngle * n > Math.PI && mAngle * n <= (Math.PI * 3) / 2) {
        radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width - 5, y);
      } else {
        radCtx.fillText(mData[n][0], x + 7, y + 2);
      }
    }
  },
  // 画点
  drawCircle(mData, color) {
    const r = 3; // 设置节点小圆点的半径
    for (let i = 0; i < numCount; i++) {
      const x = mCenter + (mRadius * Math.cos(mAngle * i)) * (mData[i][1] / 100);
      const y = mCenter + (mRadius * Math.sin(mAngle * i)) * (mData[i][1] / 100);
      radCtx.beginPath();
      radCtx.arc(x, y, r, 0, Math.PI * 2);
      radCtx.fillStyle = color;
      radCtx.fill();
    }
  },

  // 转图片
  saveCanvasImage() {
    const _this = this;
    setTimeout(() => {
      wx.canvasToTempFilePath({
        canvasId: ‘radarCanvas‘,
        // canvas: _this.canvas,
        success(res) {
          _this.setData({
            canvasImg: res.tempFilePath,
          });
        },
      });
    }, 700);
  },

注意1 最新版 只能在page 页面中画canvas 生效    在子组件中使用  要加this    

注意2 生成图片的方法要加延时器    canvas画布是异步操作  重要 不然生成图有问题

注意3 canvas的画布和图片交替的时候 隐藏问题 利用定位 fixed  absoulted 定位到显示区外面  不然不会根据画布生成图片

小程序中canvas的问题参考

上一篇:微信小程序函数执行顺序问题


下一篇:微信小程序总结