javascript - 如何使用 HTML5 canvas 绘制 donut

标签 javascript html canvas

我想在 HTML5 canvas 中绘制 donut 。如果 Canvas 的背景颜色是纯色,我可以绘制它。但是是渐变色,画不出来。

我想知道当 Canvas 的背景颜色是渐变色时,如何绘制 donut 。

喜欢:

Example of d.chart

Source

这是我的代码:

function background(context, coordinate, properties) {
  var x = coordinate.x //起始点x
  , y = coordinate.y //起始点 y
  , w = coordinate.w //宽度(终点-起始点之间的宽度)
  , h = coordinate.h //高度(终点-起始点之间的高度)
  , gradientFactor, gradientColor; //渐变因子, 渐变色

  context.save();
  switch( properties["background-fill-type"] ) {
     case "solid":
       context.fillStyle = properties["background-color"];
       break;
     case "gradient":
       gradientFactor = properties["background-gradient-factor"];
       gradientColor = context.createLinearGradient(x, y, x + w, y);
       gradientColor.addColorStop(gradientFactor, properties["background-first-color"]);
       gradientColor.addColorStop(1 - gradientFactor, properties["background-second-color"]);
       context.fillStyle = gradientColor;
       break;
     case "image":
       break;
   }
   context.fillRect(x, y, w, h);
   context.restore();
}
  1. 如果 Canvas 的背景颜色是纯色:
var context = canvas.getContext("2d")
  , properties = {
     "background-fill-type": "solid", //solid color
     "background-color": "#FFFFFF",
     "background-first-color": "#008B8B",
     "background-second-color": "#F5DEB3",
     "background-gradient-factor": 0.5,
     "border-color": "#FFFFFF",
     "border-thickness": 0
};

//draw canvas background (solid color)
background(context, {
     x: 0,
     y: 0,
     w: properties["width"],
     h: properties["height"]
}, properties);

//draw doughnut
context.save();
context.beginPath();
context.translate(centerX, centerY);
context.arc(0, 0, Radius, 0, dpi, false); //外部圆
context.fillStyle = "blue";
context.fill();    
context.closePath();

context.beginPath();
context.arc(0, 0, radius, 0, dpi, false); //内部圆
context.fillStyle = properties["background-color"];
context.fill();
context.closePath();
context.restore();
  1. 如果 Canvas 的背景颜色是渐变色:
var context = canvas.getContext("2d")
   , properties = {
         "background-fill-type": "gradient", //gradient color
         "background-color": "#FFFFFF",
         "background-first-color": "#008B8B",
         "background-second-color": "#F5DEB3",
         "background-gradient-factor": 0.5,
         "border-color": "#FFFFFF",
         "border-thickness": 0
   };

     //draw canvas background (gradient color)
     background(context, {
         x: 0,
         y: 0,
         w: properties["width"],
         h: properties["height"]
     }, properties);

    //draw doughnut
    context.save();
    context.beginPath();
    context.translate(centerX, centerY);
    context.arc(0, 0, Radius, 0, dpi, false); //外部圆
    context.fillStyle = "blue";
    context.fill();    
    context.closePath();

    context.beginPath();
    context.arc(0, 0, radius, 0, dpi, false); //内部圆
    //context.fillStyle = properties["background-color"];
    // *----------------------------------------------------------------------*
    // | How to solve internal circle and canvas background color consistent? |
    // | 
    // *----------------------------------------------------------------------*
    context.fill();
    context.closePath();
    context.restore();

这是效果图(有点歪,- -!):

enter image description here

最佳答案

绘制带有渐变背景的数据环

enter image description here

你的 donut 只是一个中心被切掉的圆圈。

所以先画一个外圈,再画一个内圈来切一个 donut 。

要显示数据,外圈可以由弧线组成,弧线的扫掠指示您的数据(称为楔形)。

您可以通过提供圆弧的起始 Angular 和结束 Angular (以弧度为单位)来绘制单独的楔形。

    ctx.arc(cX, cY, radius, startRadians, endRadians, false);

用相同的渐变填充 Canvas 和内圈以显示一致的渐变。

这是代码和 fiddle :http://jsfiddle.net/m1erickson/ENZD9/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>

    <script>
    $(function(){

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

        // define the donut
        var cX = Math.floor(canvas.width / 2);
        var cY = Math.floor(canvas.height / 2);
        var radius = Math.min(cX,cY)*.75;

        // the datapoints
        var data=[];
        data.push(67.34);
        data.push(28.60);
        data.push(1.78);
        data.push(.84);
        data.push(.74);
        data.push(.70);

        // colors to use for each datapoint
        var colors=[];
        colors.push("teal");
        colors.push("rgb(165,42,42)");
        colors.push("purple");
        colors.push("green");
        colors.push("cyan");
        colors.push("gold");

        // track the accumulated arcs drawn so far
        var totalArc=0;

        // draw a wedge
        function drawWedge2(percent, color) {
            // calc size of our wedge in radians
            var WedgeInRadians=percent/100*360 *Math.PI/180;
            // draw the wedge
            ctx.save();
            ctx.beginPath();
            ctx.moveTo(cX, cY);
            ctx.arc(cX, cY, radius, totalArc, totalArc+WedgeInRadians, false);
            ctx.closePath();
            ctx.fillStyle = color;
            ctx.fill();
            ctx.restore();
            // sum the size of all wedges so far
            // We will begin our next wedge at this sum
            totalArc+=WedgeInRadians;
        }

        // draw the donut one wedge at a time
        function drawDonut(){
            for(var i=0;i<data.length;i++){
                drawWedge2(data[i],colors[i]);
            }
            // cut out an inner-circle == donut
            ctx.beginPath();
            ctx.moveTo(cX,cY); 
            ctx.fillStyle=gradient;
            ctx.arc(cX, cY, radius*.60, 0, 2 * Math.PI, false);
            ctx.fill(); 
        }

        // draw the background gradient
        var gradient = ctx.createLinearGradient(0,0,canvas.width,0);
        gradient.addColorStop(0, "#008B8B");
        gradient.addColorStop(0.75, "#F5DEB3");
        ctx.fillStyle = gradient;
        ctx.fillRect(0,0,canvas.width,canvas.height);

        // draw the donut
        drawDonut();

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

    </head>

    <body>
        <canvas id="canvas" width=400 height=300></canvas>
    </body>
    </html>

关于javascript - 如何使用 HTML5 canvas 绘制 donut ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15898236/

相关文章:

java - 网络套接字失败。降级到 Comet 并重新发送

javascript - 不使用 .toFixed() 将浮点格式设置为两位小数

javascript - Bootstrap 工具提示不适用于我的 Web 项目

javascript - 如何在提交之前运行 javascript 函数?

javascript - HTML5 Canvas 的调整大小功能

javascript - 将 JS Canvas 元素与另一个元素切换

Javascript 与 MySQL 数据库交互

javascript - bootstrap 4 中 flex-grow div 内的垂直溢出

jquery - 如何将 "options"对齐到 kendo 下拉列表的 "select"?

javascript - 在 HTML5 中裁剪图像