canvas 环形进度条 示例 封装

在这里插入图片描述

示例

思路整理

用canvas绘制一个环形
在把一个 标注定位在canvas上方 (也可以用canvas绘制)

代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>环形进度条-canvas-函数封装</title>
    <style>
        ._con_{
            width: 300px;
            height: 300px;
            outline: 1px solid;
            position: relative;
        }
        ._con_ > .text{
            height: 100%;
            text-align: center;
            position: absolute;
            top: 0;
            width: 100%;
            line-height: 300px;
        }

    </style>
</head>
<body>
    <div class="_con_">
        <canvas id="mycanvas" width="300" height="300"></canvas>
        <div class="text">  </div>
    </div>


    <script>

        // 宽高直接写在标签上
        const ctx = document.getElementById("mycanvas").getContext("2d");

		//外圆环
        ctx.beginPath();
        // 中心坐标 x y 半径 起始角(弧的圆形的三点钟位置是 0 度) 结束角 counterclockwise:False = 顺时针,true = 逆时针。
		ctx.arc(150, 150, 100, 0, 2 * Math.PI); // 
		ctx.strokeStyle = "#fff";  // 边界颜色 类似 border
		ctx.fillStyle = "#EDEDED"; // 填充色
		ctx.fill(); // 进行填充
        ctx.stroke(); 
        
        //内圆环
		// ctx.beginPath();
		// ctx.arc(150, 150, 90, 0, 2 * Math.PI);
		// ctx.strokeStyle = "#fff";
		// ctx.fillStyle = "#fff";
		// ctx.fill();
        // ctx.stroke();

        var text = document.getElementsByClassName("text")[0]
        console.log(text)
        var press = 0.9,percent = 0
        function animate(){
            requestAnimationFrame(function (){ //屏幕刷新频率
                fun()
                text.innerText =  (percent * 100).toFixed(0) + "%"
                percent += 0.05
                if (percent < press) {
                    animate();
                }
            });
        }

        animate()

        // 圆环
        function fun(){
             //  1.5 -0.5  1  -0.5 
            // 1.5*Math.PI 正上方
            // 画圆 填充边界线 内部填充  Math.PI = 180度   
            ctx.beginPath(); 
            // 顺时针 -Math.PI / 2,-Math.PI / 2 + percent * (Math.PI * 2),false)
            // 逆时针 1.5*Math.PI, (1.5-(percent*2))
            ctx.arc( 150,150, 96, 1.5*Math.PI, (1.5-(percent*2))*Math.PI ,true);
            ctx.lineWidth = 8;
            ctx.lineCap = "round"; // lineCap 属性设置或返回线条末端线帽的样式。
            ctx.strokeStyle = "#19c6c1"//"rgb(255, 127, 105)";
            ctx.stroke();
        }


    </script>
</body>
</html>
效果

在这里插入图片描述

封装

代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>环形进度条-canvas-函数封装</title>
</head>
<body>
    <div class="con"></div>

    <script>
        function LoopProgress(obj){
            this.container = obj.container;  // 进度条放置容器
            this.gress = obj.gress;   // 初始进度
            this.width = parseInt(obj.width || '400px'); 
            this.height = parseInt(obj.height || '400px');
            this.lineColor = obj.lineColor || "#00fd54"; //进度条颜色
            this.lineWidth =  parseInt(obj.lineWidth || 15),  //进度条宽度
            // this.animationTime = obj.animationTime || 1;   //进度条时间
            this.textDom = obj.textDom  // 中间文本对象
            this.textDomFun = obj.textDomFun // 中间文本对象更新回调函数
            this.dom;
            this.canvas;
            this.ctx;
            this.text;
        }

        var container = document.getElementsByClassName("con")[0]
        

        LoopProgress.prototype.init = function(){
            this.dom = this.createDom()
            this.container.appendChild(this.dom)
            this.canvasInit()
            this.textInit(0)
            this.setPerss()
        }

        // 生成dom节点
        LoopProgress.prototype.createDom = function(){
            var con = document.createElement("div")
            var canvas = document.createElement("canvas")
            var text = document.createElement("div")

            con.style.width = this.width + "px"
            con.style.height = this.height + "px"
            con.style.position = "relative"

            canvas.setAttribute("width",this.width)
            canvas.setAttribute("height",this.height)

            text.style.width = this.width + "px"
            text.style.height = this.height + "px"
            text.style.lineHeight = this.height + "px"
            text.style.position = "absolute"
            text.style.top = "0"
            text.style.textAlign = "center"
            
            con.appendChild(canvas)
            con.appendChild(text)

            this.canvas = canvas
            this.text = text
            return con
        }

        // canvas 初始化 文字初始化
        LoopProgress.prototype.canvasInit = function(){
            var ctx = this.canvas.getContext("2d");
            ctx.beginPath();
            // 中心坐标 x y 半径 起始角(弧的圆形的三点钟位置是 0 度) 结束角 counterclockwise:False = 顺时针,true = 逆时针。
            ctx.arc(this.width/2, this.height/2, this.height/2, 0, 2 * Math.PI); // 
            ctx.strokeStyle = "#fff";  // 边界颜色 类似 border
            ctx.fillStyle = "#EDEDED"; // 填充色
            ctx.fill(); // 进行填充
            ctx.stroke(); 
            this.ctx = ctx
            this.setAnnulus(0)
        }

        //  绘制圆环 
        LoopProgress.prototype.setAnnulus = function(percent){
            // 1.5*Math.PI 正上方
            // 画圆 填充边界线 内部填充  Math.PI = 180度   
            this.ctx.beginPath(); 
            // 顺时针 -Math.PI / 2,-Math.PI / 2 + percent * (Math.PI * 2),false)
            // 逆时针 1.5*Math.PI, (1.5-(percent*2))
            this.ctx.arc(this.width/2,this.height/2, this.height/2 - this.lineWidth/2, 1.5*Math.PI, (1.5-(percent*2))*Math.PI ,true);
            this.ctx.lineWidth = this.lineWidth;
            this.ctx.lineCap = "round"; // lineCap 属性设置或返回线条末端线帽的样式。
            this.ctx.strokeStyle = this.lineColor;
            this.ctx.stroke();
        }

        LoopProgress.prototype.textInit = function(num){
            !this.textDom ? this.text.innerText = num + "%" : this.text.innerHTML = this.textDom,this.textDomFun(this.text.children)
        }

        // 动态更新
        LoopProgress.prototype.setPerss = function(){
            var _this = this,
                percent = 0;

            var time = new Date().getTime()
            animate()
            function animate(){
                requestAnimationFrame(function (){ //屏幕刷新频率
                // console.log("percent:",percent,(percent * 100).toFixed(0))
                _this.setAnnulus(percent)
                _this.textInit((percent * 100).toFixed(0))
                percent += 0.05
                if (percent <= parseInt(_this.gress)*0.01) {
                    animate();
                }
            });
            }  
        }

        // 销毁
        LoopProgress.prototype.close = function(obj){
            this.dom.remove()
            obj = null
        }

        var img = document.getElementsByClassName("img")[0]
        var loop = new LoopProgress({
            container:container,
            gress:"70",
            width:"400",
            height:"400",
            lineWidth:"15",
            textDom:'<div class="img" style="width: 200px;height: 200px;"  alt="">xxx</div>',// 是否设置中间部分
            textDomFun:function(e){ // 设置之后的回调
                console.log("textDomFun",e[0])
            }
        })

        loop.init()
        var loop2 = new LoopProgress({
            container:container,
            gress:"40",
            width:"100",
            height:"100",
            lineWidth:"10",
            textDom:"" ,// 是否设置中间部分
            textDomFun:function(){ // 设置之后的回调

            }
        })

        loop2.init()
        var loop3 = new LoopProgress({
            container:container,
            gress:"30",
            width:"200",
            height:"200",
            lineWidth:"45",
            textDom:"" ,// 是否设置中间部分
            textDomFun:function(){ // 设置之后的回调

            }
        })

        loop3.init()
    </script>
</body>
</html>
效果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值