简体   繁体   English

如何清除部分画布?

[英]How to clear part of canvas?

Here is an example! 这是一个例子!

I am trying to reset the green arc inside drawValueArc() so that each time you click the change button, the green arc is removed and redrawn. 我正在尝试重置drawValueArc()的绿色弧,以便每次单击更改按钮时,绿色弧将被删除并重新绘制。 How can I remove it without removing the entire canvas? 如何在不删除整个画布的情况下将其删除? Also, as an aside, I have noticed that Math.random() * 405 * Math.PI / 180 doesn't actually always result in an arc that fits inside the gray arc, sometimes it is larger than the gray arc, why is this? 另外,另外,我注意到Math.random() * 405 * Math.PI / 180实际上并不总是产生适合灰色弧内的弧,有时它比灰色弧大,为什么这个?

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

var cx = 150;
var cy = 150;
var startRadians = 135 * Math.PI / 180;
var endRadians = 405 * Math.PI / 180;

//main arc
ctx.beginPath();
ctx.arc(cx, cy, 58, startRadians, endRadians, false);
ctx.strokeStyle="rgb(220,220,220)";
ctx.lineWidth = 38;
ctx.stroke();

$('#setRandomValue').click(function(){
  drawValueArc(Math.random() * 405 * Math.PI / 180);
});


function drawValueArc(val){
  //ctx.clearRect(0, 0, W, H);
  ctx.beginPath();
  ctx.arc(cx, cy, 58, startRadians, val, false);
  ctx.strokeStyle = "green";
  ctx.lineWidth = 38;
  ctx.stroke();
}

Drawing past boundary 绘制过去的边界

The problem you are facing is in first instance the fact you are drawing before and after a 0-degree on the circle. 您面临的问题首先是您在圆圈上0度之前和之后绘制的事实。 This can be complicated to handle as you need to split in two draws: one for the part up to 0 (360) and one 0 to the remaining part. 这可能很难处理,因为您需要分成两个绘图:一个用于零件,最多为0(360),一个零到剩余零件。

There is a simple trick you can use to make this easier to deal with and that is to deal with all angles from 0 and use an offset when you draw. 有一个简单的技巧可以让你更容易处理,也就是处理从0开始的所有角度,并在绘制时使用偏移。

Demo using redraw base (I moved it to jsfiddle as jsbin did not work for me): 演示使用重绘基础 (我将它移动到jsfiddle,因为jsbin对我不起作用):

http://jsfiddle.net/3dGLR/ http://jsfiddle.net/3dGLR/

Demo using off-screen canvas 使用离屏画布进行演示

http://jsfiddle.net/AbdiasSoftware/Dg9Jj/ http://jsfiddle.net/AbdiasSoftware/Dg9Jj/

First, some optimizations and settings for the offset: 首先,对偏移量进行一些优化和设置:

var startRadians = 0;        //just deal with angles
var endRadians = 300;
var deg2rad = Math.PI / 180; //pre-calculate this to save some cpu cycles
var offset = 122;            //adjust this to modify rotation

We will now let the main function, drawArc() do all calculations for us so we can focus on the numbers - here we also offset the values: 我们现在让main函数drawArc()为我们做所有的计算,这样我们就可以专注于数字了 - 这里我们也偏移了这些值:

function drawArc(color, start, end) {
    ctx.beginPath();

    ctx.arc(cx, cy, 58,
        (startRadians + offset) * deg2rad,
        (end + offset) * deg2rad, false);

    ctx.strokeStyle = color;
    ctx.lineWidth = 38;
    ctx.stroke();
}

Clearing the previous arc 清除前一个弧

There are several techniques to clear the previous drawn arc: 有几种技术可以清除先前绘制的弧:

  1. You can draw the base arc to an off-screen canvas and use drawImage() to erase the old. 您可以将基弧绘制到离屏画布并使用drawImage()来擦除旧的。
  2. You can do as in the following example, just re-draw it with the base color 您可以执行以下示例,只需使用基色重新绘制它
  3. As with 2. but subtracting the green arc and draw the base color from the end of the green arc to the end of the base arc. 与2.一样,但减去绿色弧并从绿色弧的末端到基弧的末端绘制基色。
  4. clearing the whole canvas with fillRect or clearRect . 使用fillRectclearRect清除整个画布。

1 and 3 are the fastest, while 4 is the slowest. 1和3是最快的,而4是最慢的。

With out re-factored function ( drawArc ) it's as easy as this: 使用重新计算的函数( drawArc )就像这样简单:

function drawValueArc(val) {
    drawArc("rgb(220,220,220)", startRadians, endRadians);
    drawArc("green", startRadians, val);
}

As everything now is 0-based concerning start we really don't need to give any other argument than 0 to the drawArc instead of startRadians . 由于现在所有内容都是基于0的,我们实际上不需要向drawArc而不是startRadians除0以外的任何其他参数。 Use the new offset to offset the start position and adjust the endRadians to where you want it to stop. 使用新偏移量来偏移起始位置,并将endRadians调整到您希望停止的位置。

As you can see in the demo, using this technique keeps everything in check without the need to draw in split. 正如您在演示中所看到的,使用此技术可以在不需要分割的情况下检查所有内容。

Tip: if you notice green artifacts on the edges: this is due to anti-alias. 提示:如果您发现边缘有绿色瑕疵:这是由于消除了别名。 Simply reduce the line width for the green color by 2 pixels (see demo 2, off-screen canvas). 只需将绿色的线宽减少2个像素(参见演示2,屏幕外画布)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM