2

emmmmm,svg也能像canvas一样绘制图像,两者的区别,大家可以自己去查一下,接下来我来给大家分享一下怎么用svg绘制echarts的仪表盘,主要使用path路径中的弧形命令A加stroke来实现的,后续会学习更多svg绘制图形,再分享给大家。

<template>
  <svg
    class="time-circle"
    xmlns="http://www.w3.org/2000/svg"
    height="120"
    width="120"
    viewBox="0 0 120 120"
  >
    <path
      v-for="(item, index) in pointArray"
      :key="index"
      :d="getPathByIndex(index)"
      :stroke="colors[index]"
      stroke-width="13"
      fill="none"
      stroke-dasharray="3,2"
      transform="translate(10,10)"
    ></path>
  </svg>
</template>
<script>
export default {
  props: {
    nums: {
      type: Array,
      default: () => [10, 10, 20]
    },
    colors: {
      type: Array,
      default: () => ['#FBBC00', '#00A8FF', '#07FE82']
    }
  },
  data() {
    return {};
  },
  computed: {
    pathStr() {
      const r = this.radius;
      return `M${r} 0 M@1 @2 A${r} ${r} 0 @5 1 @3 @4`;
      /**
      A命令的参数:A rx ry x-axis-rotation large-arc-flag sweep-flag x y

      弧形命令A的前两个参数分别是x轴半径和y轴半径,弧形命令A的第三个参数表示弧形的旋转情况,large-arc-flag(角度大小) 和sweep-flag(弧线方向),
      large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧。sweep-flag表示弧线的方向,0表示从起点到终点沿逆时针画弧,
      1表示从起点到终点沿顺时针画弧

      path路径,@1 @2当前起点坐标,@5决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧
       */ 
    },
    radius() { // 圆的半径
      return 50;
    },
    totalNum() { // 总数,根据总数算出1对应的角度数
      return this.nums.reduce((total, curValue) => total + curValue);
    },
    pointArray() {
      const r = this.radius;
      // 每个数字对应的角度
      const deg = 360 / this.totalNum;
      // 第三位表示弧度 0是小圆,1是大圆
      const pAarray = [];
      let total = 0;
      this.nums.forEach((item, index) => {
        // 当前数字之前的角度,算出起始角度
        const preDeg = deg * total;
        // 之前存在的弧度
        const preRad = (preDeg / 180) * Math.PI;  //根据三角函数算出坐标点
        const sx = r + r * Math.sin(preRad);
        const sy = r - r * Math.cos(preRad);
        // 根据自己的角度,计算是大圆还是小圆
        const dmax = deg * item <= 180 ? 0 : 1;
        pAarray.push([sx, sy, dmax]);
        total += item;
      });
      return pAarray;
    }
  },
  methods: {
    getPathByIndex(index) {
      // 起点
      const sp = this.pointArray[index];
      // 终点
      const ep = this.pointArray[
        index + 1 === this.nums.length ? 0 : index + 1
      ];
      return this.pathStr
        .replace('@1', sp[0])
        .replace('@2', sp[1])
        .replace('@3', ep[0])
        .replace('@4', ep[1])
        .replace('@5', sp[2]);
    }
  }
};
</script>

小鳄鱼
6 声望3 粉丝

啧啧啧!