• canvas 进度条


    自制可配制的canvas进度条,

        <!DOCTYPE html>
        <html>
        <head> 
            <meta charset="utf-8"> 
                <title>CanvasTest</title> 
                <style type="text/css">
                .ProgressBar{
                    width:300px;
                }
            </style>
        </head>
        <body>
    
    
            <div class="ProgressBar" currentValue="2600" currentTarget="2200" totalTarget="2500" multiple=1.5  currentTargetShow="true">progress1</div>
            <div class="ProgressBar"  currentValue="2000" currentTarget="2200" totalTarget="2500" multiple=1 currentTargetShow="false">progress2</div>
    
            <script>
                //current value
                //current target
                //total target
                //multiple  进度条长度控制,1为设计长度,小于1为缩小,大于1为加长       
                //$scale 响应式布局参数        
                var ProgressBars=document.body.querySelectorAll(".ProgressBar");
                for (var i =0 ; i <=ProgressBars.length; i++) {
    
                    var ProgressBar=ProgressBars[i];
                    var canvas=document.createElement("canvas");
    
                    var currentValue=eval(ProgressBar.getAttribute("currentValue"));
                    var currentTarget=eval(ProgressBar.getAttribute("currentTarget"));
                    var totalTarget=eval(ProgressBar.getAttribute("totalTarget"));
                    var multiple=eval(ProgressBar.getAttribute("multiple"));
                    var currentTargetShow=eval(ProgressBar.getAttribute("currentTargetShow"));
                    
                    var $fontSize=window.getComputedStyle(document.querySelector("body")).fontSize;
                    var $scale= $fontSize.substr(0,$fontSize.length-2)/16;
    
                    
                    const totalTargetWidth=300*multiple;
                    canvas.width=(160+totalTargetWidth)*$scale;
                    canvas.height=50*$scale;
                    
                    const currentValueWidth=80*$scale;//左侧当前值宽度
                    const progressHeight=30*$scale;//progress高度
                    const yStart10=10*$scale;
    
                    const textStartX=20*$scale;
                    const textStartY=33*$scale;
    
                    const currentTargetWidth=6*$scale;
    
                    
                    
                    var currentOutputWidth;
                    var current2TotalTarget=currentValue/totalTarget;
                    var current2CurrentTarget=currentValue/currentTarget;
                    var currentTargetLeft;
                    var extendCurrentTargetWidth=0;
                    var noProductWidth=0;
                    //current value> totalTarget
                    if(current2TotalTarget>=1){
                        currentOutputWidth=totalTargetWidth*$scale;
                      
    
                    }else{ //current value< totalTarget
                        
                        if(current2CurrentTarget>=1){ //current value>currentTarget
                            currentOutputWidth=currentTarget/totalTarget*totalTargetWidth*$scale;
                            extendCurrentTargetWidth=(currentValue-currentTarget)/totalTarget*totalTargetWidth*$scale;
                            //noProductWidth=(totalTarget-currentValue)/totalTarget*totalTargetWidth*$scale;
                        }else{//currentValue<currentTarget
                            currentOutputWidth=currentValue/totalTarget*totalTargetWidth*$scale;
                           
                           // extendCurrentTargetWidth=currentOutputWidth;
                        }
                          noProductWidth=(totalTarget-currentValue)/totalTarget*totalTargetWidth*$scale;
                    }
                    currentTargetLeft=currentOutputWidth+currentValueWidth-3*$scale;
    
    
    
                    //current value
                    var ctx=canvas.getContext("2d");
                    ctx.fillStyle="#dae3f3";
                    ctx.fillRect(0,yStart10,currentValueWidth,progressHeight);
                    //current value
                    ctx.fillStyle="red";ctx.font="20px 微软雅黑";
                    ctx.fillText(currentValue,textStartX,33);
                    
                    //current progress
                    ctx.fillStyle="#00b050";
                    ctx.fillRect(currentValueWidth,yStart10,currentOutputWidth,progressHeight);
    
                    //extend current
                    ctx.fillStyle="#92d050";
                    ctx.fillRect(currentValueWidth+currentOutputWidth,yStart10,extendCurrentTargetWidth,progressHeight);
                    
                    //no product——未生产
                    ctx.fillStyle="#CCC";
                    ctx.fillRect(currentValueWidth+currentOutputWidth+extendCurrentTargetWidth,yStart10,noProductWidth,progressHeight);
                    
                    //total target
                    ctx.fillStyle="#dae3f3";
                    ctx.fillRect(canvas.width-currentValueWidth,yStart10,currentValueWidth,progressHeight);
                    ctx.fillStyle="red";ctx.font="20px 微软雅黑";
                    //total target
                    ctx.fillText(totalTarget,(currentValueWidth*1.25+totalTargetWidth)*$scale,textStartY);
    
                    
                     //up down rectangle
                     if(currentTargetShow){
                         ctx.strokeStyle ="blue";
                        ctx.lineWidth=2;
                        ctx.strokeRect(currentTargetLeft,yStart10/2,currentTargetWidth,yStart10);
                        ctx.strokeRect(currentTargetLeft,yStart10/2*7,currentTargetWidth,yStart10);
                     }
                    
                    ProgressBar.appendChild(canvas);
            }
    
    
    
    
    
        </script>
    
    </body>
    </html>

    其效果图如下:

    在此demo中,最重要的一点是利用下述代码查找页面中的 class="ProgressBar"的所有进度条,并利用html的自定义属性存储从后端传递到前端的progress bar参数。

    document.body.querySelectorAll(".ProgressBar")

    如此前端引用JS 控件就如同写html5原生的标签一样自然,减少冗余代码。


    另用svg也可,但svg有一个缺点就是其绘制的图形在html中,css是可以对其进行相应的控制,若选择器使用不佳,对SVG内部会产生影响。但在选择器使用上若能避免滥用的情况下,那么用svg+CSS来实现可配置化,是一个不错的选择。
    有道无术,术尚可求;有术无道,止于术。
  • 相关阅读:
    随机生成30到四则运算题目2 (修改)
    随机生成30到四则运算题目2
    随机生成30道四则运算题目
    第一周学习进度表
    构建之法阅读笔记01
    个人简介
    个人简介
    bat 延时删除指定文件夹中的文件经验分享
    centos 7 (操作应用)-关闭防火墙
    mysql数据库迁移
  • 原文地址:https://www.cnblogs.com/chengcanghai/p/15495555.html
Copyright © 2020-2023  润新知