• canvas绘制带文本和圆点的圆环


    <template>
      <div :style="style" class="WorkRingChart">
       <canvas class="WorkRingChart-canvas" ref="canvas"></canvas>
      </div>
    </template>
    
    <script>
      import resize from '@/mixins/eventResize';
    export default {
      name: "WorkRingChart",
      props: {
        options: {
          type: Object,
          default: () => ({})
        },
         {
          type: Number,
          default: 0
        },
        height: {
          type: Number,
          default: 0
        },
        align: {
          type: String,
          default: 'left'
        },
        // 内环标签
        innerContent: {
          type: String,
          default: ''
        },
        // 外环标签
        outerContent: {
          type: String,
          default: ''
        },
        // 主标题
        mainTitle: {
          type: String,
          default: ''
        },
        // 副标题
        subTextTitle: {
          type: String,
          default: ''
        },
        // 主标题字体大小
        mainFontSize: {
          type: Number,
          default: 20
        },
        // 副标题字体大小
        subTextFontSize: {
          type: Number,
          default: 15
        },
        innerColor: {
          type: String,
          default: 'black'
        },
        outerColor: {
          type: String,
          default: 'white'
        }
      },
      mixins: [resize],
      watch: {
        options: {
          handler () {
            this.resize();
          },
          deep: true
        }
      },
      computed: {
        style () {
          return {
             `${this.options.width}%`,
            height: `${this.options.height}%`
          }
        }
      },
      mounted () {
        window.addEventListener('resize', this.resize);
        this.resize();
      },
      beforeDestroy () {
        window.removeEventListener('resize', this.resize);
      },
      methods: {
        resize() {
          /*
          @drawing_elem: 绘制对象
          @percent:绘制圆环百分比, 范围[0, 100]
          @forecolor: 绘制圆环的前景色,颜色代码
          @bgcolor: 绘制圆环的背景色,颜色代码
          */
          const innerLabel = this.options.innerContent;
          const outerLabel = this.options.outerContent;
          const mainTitle = this.options.mainTitle;
          const subTextTitle = this.options.subTextTitle;
          const drawing_elem = this.$refs['canvas'];
          if (!(drawing_elem && drawing_elem.getContext && JSON.stringify(this.options) !== '{}')) {
            return;
          }
          const { width, height } = this.$el.getBoundingClientRect();
          drawing_elem.width = width;
          drawing_elem.height = height;
          const mainFontSize = this.options.mainFontSize * height / 155;
          const subTextFontSize = this.options.subTextFontSize * height / 155;
          const context = drawing_elem.getContext("2d");
          context.font = `${14 * height / 155}px Helvetica`;
          const billWidth = context.measureText(innerLabel).width;
          const storageWidth = context.measureText(outerLabel).width;
          let textWidth = billWidth >= storageWidth ? billWidth : storageWidth;
          // const center_x = width / 2;
          // 右上文本距离圆环的间距
          const labelDistance = 10;
          // 外半径
          const _radius = (height / 2) >= (width - textWidth - labelDistance) ? (width - textWidth - labelDistance) : (height / 2);
          // 横轴坐标
          const center_x = (height / 2) >= (width - textWidth - labelDistance) ? _radius : (() => {
            if (this.options.align === 'left') {
              return _radius;
            } else if (this.options.align === 'right') {
              return (width - textWidth - labelDistance);
            }
          })();
          // 圆环粗细
          const lineWidth = 6 * height / 155;
          // 圆环间隔
          const circleDistance = 20 * height / 155;
          // 圆环顶端圆球大小
          const ballSize = 6 * height / 155;
          const total = 100;
          let value = 50;
    
          // 绘制背景圆圈
          function backgroundCircle(radius, lineWidth) {
            context.save();
            context.beginPath();
            context.lineWidth = lineWidth; //设置线宽
            context.lineCap = "round";
            context.strokeStyle = 'rgba(255,255,255,0.05)';
            context.arc(center_x, _radius, radius, 0, Math.PI * 3 / 2, false);
            context.stroke();
            context.closePath();
            context.restore();
          }
    
          //绘制运动圆环
          function foregroundCircle(n, t, radius, lineWidth, color){
            context.save();
            context.strokeStyle = color;
            context.lineWidth = lineWidth;
            context.lineCap = "round";
            const rotateDeg = Math.PI * 2 * 3 / 4 * n / t;
            context.beginPath();
            context.arc(center_x, _radius, radius,  -Math.PI / 2, rotateDeg, true); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
            context.stroke();
            context.closePath();
            context.restore();
            context.beginPath();
            if (rotateDeg > (Math.PI * 3 / 2)) {
              const angle = rotateDeg - Math.PI * 3 / 2;
              context.arc(center_x + Math.sin(angle) * radius, _radius + Math.cos(angle) * radius, ballSize,  0, Math.PI * 2);
            } else if (rotateDeg > Math.PI) {
              const angle = rotateDeg - Math.PI;
              context.arc(center_x - Math.cos(angle) * radius, _radius + Math.sin(angle) * radius, ballSize,  0, Math.PI * 2);
            } else {
              const angle = rotateDeg;
              context.arc(center_x - Math.sin(angle) * radius, _radius - Math.cos(angle) * radius, ballSize,  0, Math.PI * 2);
            }
            context.fillStyle = color;
            context.fill();
            context.closePath();
          }
    
          //绘制文字
          function text(n, color, radius, lineWidth){
            context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
            const fontSize = 14 * height / 155;
            context.fillStyle = color;
            context.font = `${subTextFontSize}px Helvetica`;
            context.fillText(subTextTitle, center_x - context.measureText(subTextTitle).width/2, _radius);
            context.font = `${mainFontSize}px Helvetica`;
            context.fillText(mainTitle, center_x - context.measureText(mainTitle).width/2, _radius + (20 * height / 155));
            context.font = `${fontSize}px Helvetica`;
            context.fillText(innerLabel, center_x + labelDistance, _radius - radius + (20 * height / 155) + Math.abs(lineWidth / 2 - fontSize) / 2);
            context.font = `${fontSize}px Helvetica`;
            context.fillText(outerLabel, center_x + labelDistance, _radius - radius + Math.abs(lineWidth / 2 - fontSize) / 2);
            context.restore();
          }
          if ((_radius - circleDistance - lineWidth) < 0) {
            return;
          }
          context.clearRect(0, 0, width, height);
          backgroundCircle(_radius - lineWidth, lineWidth);
          foregroundCircle(value, total, _radius - lineWidth, lineWidth, this.options.outerColor);
          text(value, 'white', _radius - lineWidth, lineWidth);
          backgroundCircle(_radius - circleDistance - lineWidth, lineWidth);
          foregroundCircle(value, total, _radius - circleDistance - lineWidth, lineWidth, this.options.innerColor);
          //执行动画
    //       (function drawFrame(){
    //         window.requestAnimationFrame(drawFrame);
    //         context.clearRect(0, 0, width, height);
    //         backgroundCircle();
    //         text(speed);
    //         foregroundCircle(speed);
    //         if(speed >= percent) return;
    //         speed += 1;
    //       }());
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .WorkRingChart {
      display: inline-block;
      &-canvas {
      }
    }
    </style>
    
    
  • 相关阅读:
    C++面向对象三大特性
    4G通信技术LTE介绍
    汉澳战斗檄文,跟着汉澳去战斗
    AdapterView及其子类之二:使用ListActivity及ArrayAdapter创建列表
    [置顶] Objective-C ,ios,iphone开发基础:protocol 协议(委托,代理)的声明
    C语言中几种类型所占字节数
    UART, SPI, IIC的详解及三者的区别和联系
    数学基础详解 2——概率论与数理统计
    1—机器学习简介
    Python基础(11)——反射、异常处理
  • 原文地址:https://www.cnblogs.com/smallZoro/p/13141880.html
Copyright © 2020-2023  润新知