首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带圆角的画布矩形作为进度条?

带圆角的画布矩形作为进度条?
EN

Stack Overflow用户
提问于 2013-05-02 07:12:29
回答 1查看 2.8K关注 0票数 2

我试着在画布上画一个圆角矩形的进度条,这个jsfiddle的形状是:

http://jsfiddle.net/xT3ax/

代码语言:javascript
运行
复制
this.beginPath();
this.moveTo(x + cornerRadius.upperLeft, y);
this.lineTo(x + width - cornerRadius.upperRight, y);
this.quadraticCurveTo(x + width, y, x + width, y + cornerRadius.upperRight);
this.lineTo(x + width, y + height - cornerRadius.lowerRight);
this.quadraticCurveTo(x + width, y + height, x + width - cornerRadius.lowerRight, y + height);
this.lineTo(x + cornerRadius.lowerLeft, y + height);
this.quadraticCurveTo(x, y + height, x, y + height - cornerRadius.lowerLeft);
this.lineTo(x, y + cornerRadius.upperLeft);
this.quadraticCurveTo(x, y, x + cornerRadius.upperLeft, y);
this.closePath();

有什么简单的方法可以只画出这个形状的百分比吗?或者有一个颜色的百分比,其余的是另一个颜色?

我想不出该怎么做,除非把形状分成4块或8块,然后画出组成整个形状的每条直线或曲线的百分比?像这样,但更好:

http://jsfiddle.net/xT3ax/1/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-02 12:35:31

您可以像这样绘制圆角矩形的百分比笔划:

完整的代码在底部,下面是一个提琴:http://jsfiddle.net/m1erickson/P2qTq/

首先定义矩形的尺寸。您需要水平线和垂直线的长度以及拐角半径

代码语言:javascript
运行
复制
// define the rectangle
var horizLineLength=80;
var vertLineLength=40;
var cornerRadius=25;

由于您将递增地描边rect,因此计算每个rect段的累积长度。

代码语言:javascript
运行
复制
// calc some lengths for use in percent complete
var cornerLength = 2 * cornerRadius * Math.PI;
var totalLength = cornerLength*4+horizLineLength*2+vertLineLength*2;

// calc at what accumulated length each part of the rect starts
var startT=0;                           // top line
var startTR=horizLineLength;            // top-right corner
var startR=startTR+cornerLength;        // right line
var startBR=startR+vertLineLength;      // bottom-right corner
var startB=startBR+cornerLength;        // bottom line
var startBL=startB+horizLineLength;     // bottom-left corner
var startL=startBL+cornerLength;        // left line
var startTL=startL+vertLineLength;      // top-left corner

然后使用指定的百分比增量绘制矩形

代码语言:javascript
运行
复制
// incrementally draw the rectangle
// based on the specified percentage
function drawPercentRect(percent){

    // use percent to calc the length-traveled-along-rect
    accumLength = percent/100 * totalLength;

    // clear the canvas
    // draw the approprate portion of the  top line
    // draw the approprate portion of the  top-right corner
    // draw the approprate portion of the  right line
    // draw the approprate portion of the  bottom-right corner
    // draw the approprate portion of the  bottom line
    // draw the approprate portion of the  bottom-left corner
    // draw the approprate portion of the  left line
    // draw the approprate portion of the  top-left corner
}

您需要确定要绘制的每个线段的适当长度

对于线,计算所需线的长度。如果需要完全绘制线条,请将绘制的线条尺寸钳制到该线条的最大长度。然后绘制从起点到计算出的终点的直线。

代码语言:javascript
运行
复制
    // top line
    d=accumLength-startT
    d=Math.min(d,horizLineLength);
    if(d>0){
        x1 = offsetX + cornerRadius;
        y1 = offsetY;
        x2 = offsetX + cornerRadius + d;
        y2 = offsetY;
        drawLine(x1,y1,x2,y2);
    }

对于拐角,计算所需圆弧的长度。如果需要完全绘制拐角,请将圆弧尺寸夹紧到拐角的最大长度。然后绘制从计算起点到计算终点的圆弧放样。

代码语言:javascript
运行
复制
    // top-right corner
    d=accumLength-startTR;
    d=Math.min(d,cornerLength);
    if(d>0){
        x = offsetX + cornerRadius + horizLineLength;
        y = offsetY + cornerRadius;
        start = -Math.PI/2;
        end   = -Math.PI/2 + (d/cornerLength * Math.PI/2) ;
        drawCorner(x,y,start,end);    
    }

这是完整的代码和一个提琴:http://jsfiddle.net/m1erickson/P2qTq/

代码语言:javascript
运行
复制
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
    #slider-vertical{ height:200px; position:absolute; top:60px; left:350px; }
    #percent{ width:25px; position:absolute; top:20px; left:340px; border:0; color:blue; font-weight:bold;}
</style>

<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        // styling
        ctx.lineWidth=15;
        ctx.strokeStyle="gold";

        // define the rectangle
        var offsetX=75;
        var offsetY=100;
        var horizLineLength=80;
        var vertLineLength=40;
        var cornerRadius=25;

        // calc some lengths for use in percent complete
        var cornerLength = 2 * cornerRadius * Math.PI;
        var totalLength = cornerLength*4+horizLineLength*2+vertLineLength*2;


        // calc at what accumulated length each part of the rect starts
        var startT=0;
        var startTR=horizLineLength;
        var startR=startTR+cornerLength;
        var startBR=startR+vertLineLength;
        var startB=startBR+cornerLength;
        var startBL=startB+horizLineLength;
        var startL=startBL+cornerLength;
        var startTL=startL+vertLineLength;

        // percent complete
        var percent=100;

        // draw the radius rectangle
        function drawPercentRect(percent){

            // percent expressed as a length-traveled-along-rect
            accumLength = percent/100 * totalLength;

            // clear the canvas
            ctx.clearRect(0,0,canvas.width,canvas.height);

            // top line
            d=accumLength-startT
            d=Math.min(d,horizLineLength);
            if(d>0){
                x1 = offsetX + cornerRadius;
                y1 = offsetY;
                x2 = offsetX + cornerRadius + d;
                y2 = offsetY;
                drawLine(x1,y1,x2,y2);
            }

            // top-right corner
            d=accumLength-startTR;
            d=Math.min(d,cornerLength);
            if(d>0){
                x = offsetX + cornerRadius + horizLineLength;
                y = offsetY + cornerRadius;
                start = -Math.PI/2;
                end   = -Math.PI/2 + (d/cornerLength * Math.PI/2) ;
                drawCorner(x,y,start,end);    
            }

            // right line
            d=accumLength-startR;
            d=Math.min(d,vertLineLength);
            if(d>0){
                x1= offsetX + cornerRadius + horizLineLength + cornerRadius;
                y1= offsetY + cornerRadius;
                x2= offsetX + cornerRadius + horizLineLength + cornerRadius;
                y2= offsetY + cornerRadius + d;
                drawLine(x1,y1,x2,y2);
            }

            // bottom-right corner
            d=accumLength-startBR;
            d=Math.min(d,cornerLength);
            if(d>0){
                x = offsetX + cornerRadius + horizLineLength;
                y = offsetY + cornerRadius + vertLineLength;
                start = 0;
                end   = (d/cornerLength) * Math.PI/2;
                drawCorner(x,y,start,end);    
            }

            // bottom line
            d=accumLength-startB;
            d=Math.min(d,horizLineLength);
            if(d>0){
                x1= offsetX + cornerRadius + horizLineLength;
                y1= offsetY + cornerRadius + vertLineLength + cornerRadius;
                x2 = offsetX + cornerRadius + horizLineLength - d;
                y2 = offsetY + cornerRadius + vertLineLength + cornerRadius;
                drawLine(x1,y1,x2,y2);
            }

            // bottom-left corner
            d=accumLength-startBL;
            d=Math.min(d,cornerLength);
            if(d>0){
                x = offsetX + cornerRadius;
                y = offsetY + cornerRadius + vertLineLength;
                start = Math.PI/2;
                end   = Math.PI/2 + (d/cornerLength) * Math.PI/2;
                drawCorner(x,y,start,end);
            }

            // left line
            d=accumLength-startL;
            d=Math.min(d,vertLineLength);
            if(d>0){
                x1= offsetX;
                y1= offsetY + cornerRadius + vertLineLength;
                x2= offsetX;
                y2= offsetY + cornerRadius + vertLineLength - d;
                drawLine(x1,y1,x2,y2);
            }

            // top-left corner
            d=accumLength-startTL;
            d=Math.min(d,cornerLength);
            if(d>0){
                x = offsetX + cornerRadius;
                y = offsetY + cornerRadius;
                start = Math.PI;
                end   = Math.PI + (d/cornerLength) * Math.PI/2;
                drawCorner(x,y,start,end);
            }

        }

        function drawLine(x1,y1,x2,y2){
            ctx.beginPath();
            ctx.moveTo(x1,y1)
            ctx.lineTo(x2,y2);
            ctx.stroke();
        }

        function drawCorner(x,y,start,end){
            ctx.beginPath();
            ctx.arc(x,y,cornerRadius,start,end,false);
            ctx.stroke();
        }


        // slider for demo
        $( "#slider-vertical" ).slider({

          orientation: "vertical",
          range: "min",
          min: 0,
          max: 100,
          value: 100,
          slide: function( event, ui ) {
            $( "#percent" ).val( ui.value );
            drawPercentRect( ui.value );
          }
        });

        $( "#percent" ).val( $( "#slider-vertical" ).slider( "value" ) );

        // draw at 100% to start
        drawPercentRect(100);


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
    <input type="text" id="percent" />
    <div id="slider-vertical"></div>
</body>
</html>
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16327892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档