在画布上的彩色弧

时间:2015-03-15 20:04:58

标签: javascript html5 canvas

我想绘制具有不同颜色和半径的扇区。所以我使用canvas.arc和fill方法编写了一些代码

// constants & vars
var data=[0.2, 0.5, .5, 1.0, 0.8, .9, .7, .8];
var colors=["red", "blue", "green", "gray", "orange", 
            "rgb(255,165,0)", "rgb(100,100,100)", "black"];
var WIDTH = 200; 
var HEIGHT = 200;
var centralPoint = {x:WIDTH/2, y:HEIGHT/2};
var radius=HEIGHT/2;
var sectorsCount = data.length;
var epsilon=0.0001;
var myCanvas = document.getElementById("graphic"),
    ctx     = myCanvas.getContext('2d');
    myCanvas.height=HEIGHT;
    myCanvas.width=WIDTH;

//drawing
    for (var i=0; i<sectorsCount-1;i++) {
        ctx.moveTo(centralPoint.x, centralPoint.y);
        ctx.fillStyle=colors[i];
        ctx.arc(centralPoint.x,centralPoint.y, 
            radius*data[i], 
            i*2*Math.PI/sectorsCount+epsilon , 
            (i+1)*2*Math.PI/sectorsCount-epsilon,
             false);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    }
    ctx.fillStyle="black";
    ctx.arc(centralPoint.x,centralPoint.y, 10, 0, Math.PI*2, true);
    ctx.fill();

问题是当下一个扇区正在绘制时,前一个扇区也会变色。所以最后我有不同半径但具有相同(最后)颜色的扇区。

可能有更简单的方法来做同样的事情?

2 个答案:

答案 0 :(得分:2)

在绘制新弧之前添加beginPath()

for (var i=0; i<sectorsCount-1;i++) {
    ctx.beginPath();     // <--- needs beginPath() here
    ctx.moveTo(centralPoint.x, centralPoint.y);

如果不是,则会累积路径对象。下次使用填充/描边时,将填充/描边所有路径对象。这与清除画布无关,因此需要使用beginPath()清除路径。

希望这会有所帮助 - 请参阅以下更新:

// constants & vars
var data=[0.2, 0.5, .5, 1.0, 0.8, .9, .7, .8];
var colors=["red", "blue", "green", "gray", "orange", "rgb(255,165,0)", "rgb(100,100,100)", "black"];
var WIDTH = 200; 
var HEIGHT = 200;
var centralPoint = {x:WIDTH/2, y:HEIGHT/2};
var radius=HEIGHT/2;
var sectorsCount = data.length;
var epsilon=0.0001;
var myCanvas = document.getElementById("graphic"),
    ctx     = myCanvas.getContext('2d');
    myCanvas.height=HEIGHT;
    myCanvas.width=WIDTH;

//drawing
    for (var i=0; i<sectorsCount-1;i++) {
        ctx.beginPath();
        ctx.moveTo(centralPoint.x, centralPoint.y);
        ctx.fillStyle=colors[i];
        ctx.arc(centralPoint.x,centralPoint.y, 
            radius*data[i], 
            i*2*Math.PI/sectorsCount+epsilon , 
            (i+1)*2*Math.PI/sectorsCount-epsilon,
             false);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    }
    ctx.fillStyle="black";
    ctx.arc(centralPoint.x,centralPoint.y, 10, 0, Math.PI*2, true);
    ctx.fill();
<canvas id="graphic" />

答案 1 :(得分:2)

路径绘制命令以context.beginPath开头,一直有效,直到下一个context.beginPath。因此,如果没有新的beginPath,所有以前的楔形都将使用最后一个楔形重绘。

因此,简单的解决方法是确保每个楔形都以beginPath开头:

&#13;
&#13;
var data=[0.2, 0.5, .5, 1.0, 0.8, .9, .7, .8];
var colors=["red", "blue", "green", "gray", "orange", "rgb(255,165,0)", "rgb(100,100,100)", "black"];
var WIDTH = 200; 
var HEIGHT = 200;
var centralPoint = {x:WIDTH/2, y:HEIGHT/2};
var radius=HEIGHT/2;
var sectorsCount = data.length;
var epsilon=0.0001;
var myCanvas = document.getElementById("graphic"),
    ctx     = myCanvas.getContext('2d');
myCanvas.height=HEIGHT;
myCanvas.width=WIDTH;

//drawing
for (var i=0; i<sectorsCount-1;i++) {
  ctx.beginPath();
  ctx.moveTo(centralPoint.x, centralPoint.y);
  ctx.fillStyle=colors[i];
  ctx.arc(centralPoint.x,centralPoint.y, 
          radius*data[i], 
          i*2*Math.PI/sectorsCount+epsilon , 
          (i+1)*2*Math.PI/sectorsCount-epsilon,
          false);
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
}
ctx.fillStyle="black";
ctx.beginPath();
ctx.arc(centralPoint.x,centralPoint.y, 10, 0, Math.PI*2, true);
ctx.fill();
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid red;}
&#13;
<canvas id="graphic" width=300 height=300></canvas>
&#13;
&#13;
&#13;