CSS - how to create circle pie canvas like this?

前端 未结 5 919
醉酒成梦
醉酒成梦 2021-01-05 20:03

I really like this element,

\"this

but how to create it? I am not sure what\'s the correct de

相关标签:
5条回答
  • 2021-01-05 20:06

    FIDDLE with ANIMATION

    Here's my approach:

    var ctx = canvas.getContext('2d');
    
    
    /*
     * in canvas, 0 degrees angle is on the right edge of a circle,
     * while we want to start at the top edge of the circle.
     * We'll use this variable to compensate the difference.
     */
    var relativeAngle = 270;
    
    function drawCanvas() {
    
        ctx.clearRect(0, 0, 90, 90);
        //light blue circle
        ctx.lineWidth = 20;
        ctx.strokeStyle = '#D8E8F7';
        ctx.beginPath();
        ctx.arc(45, 45, 35, 0, 2*Math.PI);
        ctx.stroke();
    
        //dark blue circle
        ctx.strokeStyle = '#66ADF4';
        ctx.beginPath();
        //notice the angle conversion from degrees to radians in the 5th argument
        ctx.arc(45, 45, 35, 1.5*Math.PI, ((angle + relativeAngle) / 180) * Math.PI);
        ctx.stroke();
    
        //text
        ctx.textBaseline = 'middle';
        ctx.textAlign = 'center';
        ctx.fillStyle = '#666';
        ctx.font = 'bold 14px serif';
        // angle conversion to percentage value
        ctx.fillText(parseInt(100 * angle / 360).toString() + '%', 45, 45);
    }
    
    var angle;
    function timeout() {
        angle = parseInt(360 * percent / 100);
        drawCanvas();
    
        if (angle > 360) {
            document.getElementById('run').disabled = false;
            percent = 0;
            return;
        }
    
        percent++;
        setTimeout(timeout, 10);
    };
    
    var percent = 0;
    
    /* START the ANIMATION */
    timeout();
    

    At the bottom of the code you'll find a self evaluating function timeout which calls the drawCanvas function every 10 miliseconds and increments the blue circle angle. I hope everything is clear here. If not, feel free to ask!

    Enjoy it!

    0 讨论(0)
  • 2021-01-05 20:08

    Instead of using the <canvas> element, I have chosen to construct the pie chart relying on CSS and JS entirely. The HTML markup is as follow:

    <div class="pie" data-percent="78">
        <div class="left">
            <span></span>
        </div>
        <div class="right">
            <span></span>
        </div>
    </div>
    

    The CSS is as follow. The trick is to split the circle into two halves (the nested .left and .right elements). The halves will have their overflowing content hidden, and contain nested <span> that we will manipulate with JS for rotation later. Add vendor prefixes when appropriate :)

    .pie {
        background-color: #eee;
        border-radius: 50%;
        width: 200px;
        height: 200px;
        overflow: hidden;
        position: relative;
    }
    .pie > div {
        float: left;
        width: 50%;
        height: 100%;
        position: relative;
        overflow: hidden;
    }
    .pie span {
        background-color: #4a7298;
        display: block;
        width: 100%;
        height: 100%;
    }
        .pie .left span {
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
            -webkit-transform-origin: 100% 50%;
            transform-origin: 100% 50%;
        }
        .pie .right span {
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
            -webkit-transform-origin: 0% 50%;
            transform-origin: 0% 50%;
        }
    .pie:before,
    .pie:after {
        border-radius: 50%;
        display: block;
        position: absolute;
        top: 50%;
        left: 50%;
        -webkit-transform: translateX(-50%) translateY(-50%);
        transform: translateX(-50%) translateY(-50%);
    }
        .pie:before {
            background-color: #fff;
            content: "";
            width: 75%;
            height: 75%;
            z-index: 100;
        }
        .pie:after {
            content: attr(data-percent) "%";
            z-index: 200;
            text-align: center;
        }
    

    I have used the following with jQuery:

    $(function() {
        $(".pie").each(function() {
            var percent = $(this).data("percent").slice(0,-1), // Removes '%'
                $left = $(this).find(".left span"),
                $right = $(this).find(".right span"),
                deg;
    
            if(percent<=50) {
                // Hide left
                $left.hide();
    
                // Adjust right
                deg = 180 - (percent/100*360)
                $right.css({
                    "transform": "rotateZ(-"+deg+"deg)"
                });
            } else {
                // Adjust left
                deg = 180 - ((percent-50)/100*360)
                $left.css({
                    "transform": "rotateZ(-"+deg+"deg)"
                });
            }
        });
    });
    

    Here is the fiddle: http://jsfiddle.net/Aw5Rf/7/

    0 讨论(0)
  • 2021-01-05 20:09

    This effect can be achieved by layering a couple arc()s:

    // bright blue full circle
    d.beginPath();
    d.arc(50, 50, 50, 0, 2 * Math.PI, false);
    d.fillStyle = "#aaeeff";
    d.fill();
    
    // dark blue percentage circle
    d.beginPath();
    d.moveTo(50, 50);
    d.arc(50, 50, 50, -0.5 * Math.PI, 0.78 * 2 * Math.PI - 0.5 * Math.PI, false);
    d.fillStyle = "#00aaff";
    d.fill();
    
    // white inner filler
    d.beginPath();
    d.moveTo(50, 50);
    d.arc(50, 50, 25, 0, 2 * Math.PI, false);
    d.fillStyle = "#ffffff";
    d.fill();
    

    and finally rendering the text:

    d.moveTo(50, 50);
    d.fillStyle = "#606060";
    d.font = "12pt sans-serif";
    d.fillText("78%", 36, 56);
    

    Fiddle: http://jsfiddle.net/j6NVg/

    0 讨论(0)
  • 2021-01-05 20:14

    Check the below links for more info (not an exact one.But you can get some idea).

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Canvas Test</title>
    </head>
    <body>
    <section>
    <div>
    <canvas id="canvas" width="400" height="300">
    This text is displayed if your browser does not support HTML5 Canvas.
    </canvas>
    </div>
    
    <script type="text/javascript">
    
    var myColor = ["#ECD078","#D95B43","#C02942","#542437","#53777A"];
    var myData = [10,30,20,60,40];
    
    function getTotal(){
    var myTotal = 0;
    for (var j = 0; j < myData.length; j++) {
    myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;
    }
    return myTotal;
    }
    
    function plotData() {
    var canvas;
    var ctx;
    var lastend = 0;
    var myTotal = getTotal();
    
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    for (var i = 0; i < myData.length; i++) {
    ctx.fillStyle = myColor[i];
    ctx.beginPath();
    ctx.moveTo(200,150);
    ctx.arc(200,150,150,lastend,lastend+
      (Math.PI*2*(myData[i]/myTotal)),false);
    ctx.lineTo(200,150);
    ctx.fill();
    lastend += Math.PI*2*(myData[i]/myTotal);
    }
    }
    
    plotData();
    
    </script>
    </section>
    </body>
    </html>
    

    For more info :Graphing Data in the HTML5 Canvas Element Simple Pie Charts

    Another Link : Pure CSS3 Pie Charts effect

    This is an online demo: http://jsbin.com/uFaSOwO/1/

    0 讨论(0)
  • 2021-01-05 20:30

    First of all what you need can be done exactly using jQuery knob plugin. Still interested in a CSS Solution, than here's what I have done

    <div class="load_me"></div>
    
    .load_me {
        margin: 100px;
        height: 50px;
        width: 50px;
        border: 5px solid #f00;
        border-radius: 50%;
        border-top-color: transparent;
    }
    

    Demo


    Animating the Knob Credits


    If you want to prevent the mouse alteration, you can simply add readOnly

    $this.knob({
        readOnly: true
    });
    

    Demo

    0 讨论(0)
提交回复
热议问题