html5,canvas实现自定义饼图

封装的vue组件

<template>
    <div class="mycanvas" ref="mycanvas">
      <canvas  ref="canvas" ></canvas>
    </div>
</template>

<script>
define(["Vue"], function(Vue) {
  var result = Vue.extend({
    template: template,
    created: function() {},
    mounted: function() {
      this.changeCanvas();
    },
    props: {
      percentvalue: String,
      textstr: String
    },
    data: function() {
      return {
        canvas: null, //获取canvas元素
        context: null, //canvas.getContext("2d"), //获取画图环境,指明为2d
        centerX: null, //canvas.width / 2, //Canvas中心点x轴坐标
        centerY: null, //canvas.height / 2, //Canvas中心点y轴坐标
        rad: Math.PI * 2 / 100, //将360度分成100份,那么每一份就是rad度
        value: 0,
        endresul: 0,
        radius: 50 //半径
      };
    },
    watch: {
      percentvalue: function(params) {
        this.updateData(params);
        this.changeCanvas();
      }
    },
    components: {},
    methods: {
      changeCanvas: function() {
        this.canvas = this.$refs.canvas;
        this.canvas.width = this.$refs.mycanvas.clientWidth;
        this.canvas.height = this.$refs.mycanvas.clientHeight;
        this.radius =
          this.canvas.width > this.canvas.height
            ? this.canvas.height / 2
            : this.canvas.width / 2;
        this.context = this.canvas.getContext("2d"); //获取画图环境,指明为2d
        this.centerX = this.canvas.width / 2; //Canvas中心点x轴坐标
        this.centerY = this.canvas.height / 2; //Canvas中心点y轴坐标
        this.drawFrame(0);
      },
      //设置事件总线
      setEventBus: function(eventBus) {
        this.eventBus = eventBus;
      },
      //设置数据模型
      setModel: function(model) {},
      //更新数据
      updateData: function(realdata) {
        this.endresul = Math.floor(Math.random() * 100); //realdata.dataSource
        //this.value= this.endresul;
      },
      drawFrame: function() {
        window.requestAnimationFrame(this.drawFrame, this.canvas);
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);

        this.OtherCircle();
        this.text1(this.textstr);
        this.ValueCircle(this.endresul);
        this.endcircle(this.endresul);
        this.textval(this.endresul);
        if (this.value > this.endresul) {
          this.value -= 1;
        } else {
          this.value += 1;
        }
      },
      endcircle: function(n) {
        this.context.save();
        this.context.strokeStyle = "white"; //设置描边样式
        this.context.lineWidth = 8; //设置线宽
        this.context.lineCap = "round";
        this.context.shadowBlur = "20";
        this.context.shadowColor = "#42cfa9";
        this.context.beginPath(); //路径开始
        this.context.arc(
          this.centerX,
          this.centerY,
          this.radius - 12,
          n * this.rad,
          n * this.rad,
          false
        ); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
        this.context.stroke(); //绘制
        this.context.closePath(); //路径结束
        this.context.restore();
      },
      ValueCircle: function(n) {
        this.context.save();
        this.context.strokeStyle = "#42cfa9"; //设置描边样式
        this.context.lineWidth = 2; //设置线宽
        this.context.lineCap = "round";
        this.context.shadowBlur = "20";
        this.context.shadowColor = "#42cfa9";
        this.context.beginPath(); //路径开始
        this.context.arc(
          this.centerX,
          this.centerY,
          this.radius - 12,
          0,
          n * this.rad,
          true
        ); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
        this.context.stroke(); //绘制
        this.context.closePath(); //路径结束
        this.context.restore();
      },
      //绘制外圈
      OtherCircle: function() {
        this.context.save();
        this.context.beginPath();
        this.context.strokeStyle = "#25363F";
        this.context.arc(
          this.centerX,
          this.centerY,
          this.radius - 12,
          0,
          Math.PI * 2,
          true
        );
        this.context.stroke();
        this.context.closePath();
        this.context.restore();
      },
      textval: function(n) {
        this.context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
        this.context.beginPath();
        // this.context.strokeStyle = "white"; //设置描边样式

        this.context.fillStyle = "white";
        this.context.font = "40px Arial"; //设置字体大小和字体
        //绘制字体,并且指定位置
        if ((100 - n.toFixed(0)).toString().length == 3) {
          this.context.fillText(
            100 - n.toFixed(0),
            this.centerX - 15,
            this.centerY + 15
          );
        } else {
          this.context.fillText(
            100 - n.toFixed(0),
            this.centerX - 5,
            this.centerY + 15
          );
        }
        this.context.stroke(); //执行绘制
        this.context.closePath(); //路径结束
        this.context.restore();
      },
      //百分比文字绘制
      text1: function(text) {
        this.context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
        this.context.beginPath();
        this.context.strokeStyle = "#42cfa9"; //设置描边样式
        this.context.font = "14px"; //设置字体大小和字体
        //绘制字体,并且指定位置
        if (text.length == 2) {
          this.context.strokeText(text, this.centerX - 40, this.centerY - 10);
        } else {
          this.context.strokeText(text, this.centerX - 55, this.centerY - 10);
        }
        this.context.strokeText("完成率", this.centerX - 45, this.centerY + 15);
        // this.context.strokeText("月度电量完成率"+n.toFixed(0), this.centerX - 55, this.centerY + 10);
        this.context.stroke(); //执行绘制
        this.context.closePath(); //路径结束
        this.context.restore();
      }
    }
  });

  Vue.component("ring-percent", result); // register to be used

  // return to be used in unit tests
  return result;
});
</script>

<style>
.mycanvas {
  width: 50%;
  float: left;
  height: 100%;
}
</style>
复制代码

转载于:https://juejin.im/post/5a6149946fb9a01cbe65626d

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值