【问题标题】:deleting a circle made in HTML5 Canvas [duplicate]删除用 HTML5 Canvas 制作的圆圈 [重复]
【发布时间】:2019-04-25 07:20:24
【问题描述】:

我制作了一个画布,可以在上面绘制形状。当我想删除它们时,我基本上会再次创建相同的形状,但它是白色的,所以我不会删除任何其他形状(保存了 x 和 y 坐标,所以不用担心)

ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#FFFFFF";

ctx.beginPath();
ctx.arc(x, y, 40, 0, 2 * Math.PI);
ctx.fill();

问题是在某些形状上仍然有剩余的黑色休息,我无法摆脱(其他形状甚至更糟)

我错过了什么?

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

ctx.beginPath();
ctx.arc(50,50 , 40, 0, 2 * Math.PI);
ctx.fill();
        		
ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#FFFFFF";
      
ctx.beginPath();
ctx.arc(50,50 , 40, 0, 2 * Math.PI);
ctx.fill();
<canvas id="myCanvas" width="1000" height=600 style="border: 1px solid #000000;">
</canvas>

编辑:https://jsfiddle.net/sfj5y091/3/

编辑 2: 我最终解决了这个问题,通过在系统中删除一个形状后完全重绘所有形状,甚至可以删除重叠的形状而不破坏另一个形状

【问题讨论】:

  • 你能给我们做一个基本的工作例子吗?也许在 JSFiddle 甚至在 StackOverflow Code example editor?
  • 你应该使用清晰的重绘不是要走的路。也许这有助于stackoverflow.com/questions/10396991/…
  • canvas 真的不具备处理将图纸视为单独对象的能力。与其重绘,不如只保存以前的状态并重新渲染它们,而不是在画布上添加更多的绘图。如果你真的必须能够单独处理绘制的东西,那么 SVG 可以更好地做到这一点。
  • 您可以有 2 个画布(一个在另一个之后),您可以将有关您正在绘制的形状的信息保存在一个结构中。当您必须擦除一个形状时,您只需重新绘制除第二个画布上擦除的形状之外的所有形状。要显示第二个画布,请放置一个大于第一个画布的 CSS z-index 属性。这称为Double buffering
  • @Fuseldieb thx 指出,有一个 StackOverflow 编辑器,这个网站很棒

标签: javascript html5-canvas shapes


【解决方案1】:

残留是由平滑或抗锯齿引起的。

为了在最初的白色背景上绘制黑色圆圈,在半径为 40 像素的圆圈的边缘绘制了一个灰色像素的“光环”,以使其外观平滑,而“光环”只是一点点比你计划画的要大。

如果您在其上绘制一个 40 像素半径的白色圆圈,它会将新的 白色 边缘像素与现在的非白色背景混合。结果是较浅的灰色像素,而不是白色像素。

如果您唯一的选择仍然是在旧像素上绘制,那么您必须为白色圆圈使用稍大的半径:

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

ctx.beginPath();
ctx.arc(50, 50, 40, 0, 2 * Math.PI); // radius of 40
ctx.fill();

ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";

ctx.beginPath();
ctx.arc(50, 50, 41, 0, 2 * Math.PI); // radius of 41
ctx.fill();
<canvas id="myCanvas" width="150" height="150" style="border: 1px solid #000000;">
</canvas>
<br /> Nothing to see here ;-)

有关抗锯齿的更多信息,请参见例如Can I turn off antialiasing on an HTML <canvas> element?

【讨论】:

  • 谢谢,解决了!
  • 对原因的解释是正确的,但解决方案很糟糕......画大只会将问题移开几个像素,它不会解决它。
【解决方案2】:

双缓冲作用

试试

step1();

setTimeout(function () {

  step2();

  setTimeout(function () {

    step3();

  }, 1000);
}, 1000);

function step1() {
  clearCanvas('myCanvas1');

  drawShape('myCanvas1'
     ,{type:"circle", strokeStyle:"#000000", fillStyle:"#000000", radious:40, x:50, y:50});
};

function step2() {
  clearCanvas('myCanvas2');

  showOtherCanvas('myCanvas2', 'myCanvas1');
};

function step3() {
  clearCanvas('myCanvas1');

  drawShape('myCanvas1'
     ,{type:"circle", strokeStyle:"#000000", fillStyle:"#000000", radious:40, x:50, y:50});

  showOtherCanvas('myCanvas1', 'myCanvas2');
};

function drawCircle (canvasID, info) {
  var canvas = document.getElementById(canvasID);
  var ctx = canvas.getContext('2d');
  
  ctx.fillStyle=info.fillStyle;
  ctx.strokeStyle=info.strokeStyle;

  ctx.beginPath();
  ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
  ctx.fill();

  ctx.beginPath();
  ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
  ctx.stroke();
}

function showOtherCanvas(cnv1, cnv2) {
  var c1 = document.getElementById(cnv1);
  var c2 = document.getElementById(cnv2);
  
  c1.style['z-index'] = 3;
  c2.style['z-index'] = 1;
  c1.style['z-index'] = 2;
}

function clearCanvas(canvasID) {
  var canvas = document.getElementById(canvasID);
  var ctx = canvas.getContext('2d');
  
  ctx.fillStyle="#FFFFFF";
  ctx.strokeStyle="#FFFFFF";
  
  ctx.fillRect(0,0,640,400);
} 



function drawShape (canvasID, info) {
  switch (info.type) {
    case  "circle" : drawCircle(canvasID, info);
  }
}
<canvas id="myCanvas2" width="640" height="400"
	style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
</canvas>
<canvas id="myCanvas1" width="640" height="400"
	style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
</canvas>

变化如此之快,你不会看到任何闪烁。

【讨论】:

  • 我是画布的初学者,你在这个函数中到底在做什么?
  • @l33t5p34k3r drawCircle 只是画了一个带边框的圆(边框可以是相同的颜色)。双缓冲位是有趣的部分。如果您在黑色圆圈上绘制一个白色圆圈以隐藏黑色圆圈,您总是会看到视觉伪影。而且由于画布不记得您要求绘制的内容,如果您想擦除某些内容,则必须重绘所有内容,并且双缓冲使重绘看起来是即时的。玩它,添加新形状,改变时间,玩得开心。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-08
  • 2011-05-15
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多