<canvas>+JS如何实现可拖拽并且显示百分比的环形进度条

canvas+JS如何实现可拖拽并且显示百分比的环形进度条
思维导图:
这里写图片描述

HTML部分:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>test</title>
    </head>
    <body>
        <canvas id="test" width="200" height="200"></canvas>
        <script src="js/drafting.js"></script>
        <script type="text/javascript">
            var canvasId = document.getElementById("test");
            var drag1 = new DraftingByZM({
                //必传参数,注意此处必须传原生对象,不能是jQuery对象
                canvasByZM: canvasId
            });
        </script>
    </body>
</html>

js组件:

/**
 * 
 * @authors ZM
 * @date    2017-09-05 18:42:09
 * @version 1.0
 */
DraftingByZM = (function(){
    var Obj = function(options){
        this._setPara(options);
        this.init();
    };
    Obj.prototype = {
        constructor: Obj,
        author: "ZM",
        version: 1.0,
        //入口方法
        init: function(){
            this._check();
            this._eventListen();
        },
        //画圆
        _check: function(){
            //简单校验,查看是否支持HTML5<canvas></canvas>标签
            if(this.canvasByZM.getContext){
                this._circlePara();
                //var _this = this;
                this._drawCircle(this.$Begin);//传入参数为起始位置(0到1)
            }else{
                alert('Your browser does not support this function temporarily. Please upgrade your browser version as soon as possible.');
            }
        },
        //圆的参数
        _circlePara: function(){
            this.context = this.canvasByZM.getContext('2d');//调用getContext方法,返回一个画布环境
            this.ox = 100;//圆环在画布上的x轴坐标
            this.oy = 100;//圆环在画布上的y轴坐标
            this.or = 70;//圆环半径
            this.br = 15;//圆珠半径
        },
        //根据弧度与距离计算偏移坐标
        _calOffset: function(r,d){
            return {x: -Math.sin(r)*d, y: Math.cos(r)*d};
        },
        _drawCircle: function(n){
            var ctx = this.context;
            //console.log(this.canvasByZM.width);
            ctx.clearRect(0,0,this.canvasByZM.width,this.canvasByZM.height);
            //clearRect()==>HTML5中的方法,用于擦除指定区域

            //底环 
            ctx.strokeStyle = this.$acrossColor;//底色
            ctx.lineWidth = this.$circleThinkness;//底环粗细
            ctx.beginPath();//起始一条路径,或重置当前路径
            ctx.arc(this.ox,this.oy,this.or,0,2*Math.PI,true);
            ctx.stroke();

             //有色环
            ctx.strokeStyle = this.$fillColor;//颜色
            ctx.lineWidth = this.$circleThinkness;//宽度
            ctx.beginPath();
            ctx.arc(this.ox,this.oy,this.or,0.5*Math.PI,(n*2+0.5)*Math.PI,false);
            //arc(x, y, radius, startAngle, endAngle, anticlockwise):
            //画一个以(x,y)为圆心的以radius为半径的圆弧(圆),
            //从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成
            ctx.stroke();

            //中间文字
            ctx.fillStyle = this.$fillColor;//颜色
            ctx.font = this.$FontSize +"px Arial";//字号
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            //计算数值的取值区间
            ctx.fillText(Math.round(n*100)+this.$FontUnit,this.ox,this.oy);

            //圆珠
            ctx.fillStyle = this.$fillColor;
            ctx.beginPath();
            var d =  this._calOffset(n*2*Math.PI,this.or);
            console.log(d);
            ctx.arc(this.ox+d.x,this.oy+d.y,this.br,0,2*Math.PI,true);
            ctx.fill();
        },
        //获取鼠标当前坐标
        _getXY: function(e) {
            var _this = this;
            var et = e.touches? e.touches[0] : e;
            var x = et.clientX;
            var y = et.clientY;
            console.log(x);
            console.log(y);
            return {
                x : x - _this.canvasByZM.getBoundingClientRect().left + (document.body.scrollLeft || document.documentElement.scrollLeft),
                y : y - _this.canvasByZM.getBoundingClientRect().top + (document.body.scrollTop || document.documentElement.scrollTop)
                // x : x - _this.canvasByZM.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft),
                // y : y - _this.canvasByZM.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop)
                //offsetLeft存在一定兼容性问题,其在有些浏览器中是根据父元素获取其偏移值,
                //有些却是根据body元素获取偏移值。
                //这里可以使用getBoundingClientRect获取对应元素到视窗的距离
            }
        },
        //监听事件
        _eventListen: function(){
            //是否支持触屏
            var on = ("ontouchstart" in document)? {
                start: "touchstart", move: "touchmove", end: "touchend"
            } : {
                start: "mousedown", move: "mousemove", end: "mouseup"
            };

            var _this = this;
            this.canvasByZM.addEventListener(on.end, function(e) {
                _this.moveFlag = false;
            }, false);
            this.canvasByZM.addEventListener(on.start, function(e) {
                _this.moveFlag = true;
            }, false);
            this.canvasByZM.addEventListener(on.move, function(e) {
                if (_this.moveFlag) {
                    //获取坐标
                    var k = _this._getXY(e);
                    //计算弧度
                    var r = Math.atan2(k.x-_this.ox,_this.oy-k.y);
                    //画圆
                    _this._drawCircle((Math.PI+r)/(2*Math.PI));
                }
            }, false);
        },

        //设置参数
        _setPara: function(option){
            this.canvasByZM = option.canvasByZM;
            this.$circleThinkness = option.$circleThinkness || 10;
            this.$acrossColor = option.$acrossColor || "#ccc";
            this.$fillColor = option.$fillColor || "#ff5151";
            this.$FontUnit = option.$FontUnit || "%";
            this.moveFlag = false;//开关
            this.$Begin = parseFloat(option.$Begin) || 0.5;
            this.$FontSize = option.$FontSize || 50;
        },
        remove: function(){ // 移除组件
            //清除事件
            this.canvasByZM.onmousedown = null;
            this.canvasByZM.onmousemove = null;
            this.canvasByZM.onmouseup = null;
            // 释放内存
            for (var i in this){
                this[i] = null;
            }
        }
    };
    return Obj;
})();
//调用示例
// var drag1 = new DraftingByZM({
//  //必传参数,注意此处必须传原生对象,不能是jQuery对象
//  canvasByZM: $("#canvas1")[0],
//  //可选参数
//  $circleThinkness:10,      //元环粗细
//  $acrossColor:"#ccc",      //底环颜色
//  $fillColor:"#ff5151",     //顶环颜色
//  $FontUnit:"°",            //数字单位
//  $Begin:0.7,//(0-1)        //起始位置
//  $FontSize:70              //文字大小
// });

使用方法,将js组件部分存为后缀为.js的文件,引入到HTML文档中,按调用示例调用。

猜你喜欢

转载自blog.csdn.net/here962464/article/details/78087443