zoukankan      html  css  js  c++  java
  • 小程序中canvas的问题参考

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

    参考: https://juejin.cn/post/6983574104167170061

    参考: https://developers.weixin.qq.com/miniprogram/dev/extended/component-plus/wxml-to-canvas.html   

    canvas文本绘制自动换行、字间距、竖排等实现

    更优雅地基于 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 定位到显示区外面  不然不会根据画布生成图片

    苦心人,天不负
  • 相关阅读:
    用Instant client批量安装Oracle客户端安装配置
    Oracle case when 用法(转)
    C# 读写ini文件 【转】
    oracle数据库删除数据Delete语句和Truncate语句的对比
    C#使用instantclient连接 Oracle 10g (转)
    SQL Server CONVERT() 函数
    c#格式化数字(转)
    InstantClient安装使用 (转)
    C# 四个字节十六进制数和单精度浮点数之间的相互转化
    oracle case when的使用方法
  • 原文地址:https://www.cnblogs.com/taxun/p/15012027.html
Copyright © 2011-2022 走看看