如何清除画布以重画

这篇博客讨论了在HTML5 Canvas上清除图像并进行重画的各种方法,包括使用clearRect、fillRect、宽度Hack等。作者强调了在不同场景下选择合适清除策略的重要性,特别提到了在处理变换后的坐标时需要注意的问题。博客提供了多个示例代码片段,展示了如何有效地清除画布以准备重画。

在尝试了复合操作并在画布上绘制图像之后,我现在尝试删除图像并进行合成。 我该怎么做呢?

我需要清除画布才能重画其他图像; 这可能会持续一段时间,所以我不认为每次都绘制一个新的矩形将是最有效的选择。


#1楼

这些都是清除标准画布的绝佳示例,但是,如果您使用的是paperjs,则可以使用:

JavaScript中定义全局变量:

var clearCanvas = false;

从PaperScript中定义:

function onFrame(event){
    if(clearCanvas && project.activeLayer.hasChildren()){
        project.activeLayer.removeChildren();
        clearCanvas = false;
    }
}

现在,无论将clearCanvas设置为true哪里,它都会清除屏幕上的所有项目。


#2楼

这里有很多好的答案。 还有一点要注意的是,有时只将画布部分清除是很有趣的。 也就是说,“淡出”先前的图像,而不是完全擦除它。 这可以给人留下深刻的印象。

这很容易。 假设您的背景色是白色:

// assuming background color = white and "eraseAlpha" is a value from 0 to 1.
myContext.fillStyle = "rgba(255, 255, 255, " + eraseAlpha + ")";
myContext.fillRect(0, 0, w, h);

#3楼

最快的方法:

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

//... some drawing here

i = c.createImageData(canvas.width, canvas.height);
c.putImageData(i, 0, 0); // clear context by putting empty image data

#4楼

我发现,在我测试过的所有浏览器中,最快的方法是用白色或任何您想要的颜色填充Rect。 我有一个非常大的监视器,在全屏模式下,clearRect非常慢,但是fillRect是合理的。

context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);

缺点是画布不再透明。


#5楼

通过传递x,y坐标以及画布的高度和宽度来使用clearRect方法。 ClearRect会将整个画布清除为:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);

#6楼

const context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);

#7楼

function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}

#8楼

在Webkit中,您需要将宽度设置为其他值,然后可以将其设置回初始值


#9楼

这适用于chart.js中的pieChart

<div class="pie_nut" id="pieChartContainer">
    <canvas id="pieChart" height="5" width="6"></canvas> 
</div>

$('#pieChartContainer').html(''); //remove canvas from container
$('#pieChartContainer').html('<canvas id="pieChart" height="5" width="6"></canvas>'); //add it back to the container

#10楼

  • Chrome对以下内容的响应良好: context.clearRect ( x , y , w , h ); 如@ Pentium10所建议,但IE9似乎完全忽略了此指令。
  • IE9似乎响应: canvas.width = canvas.width; 但是除非您也使用@John Allsopp的先更改宽度的解决方案,否则它不会清除线条,仅清除形状,图片和其他对象。

因此,如果您具有这样创建的画布和上下文:

var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');

您可以使用如下方法:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}

#11楼

context.clearRect(0,0,w,h)   

用RGBA值填充给定的矩形:
0 0 0 0:使用Chrome
0 0 0 255:使用FF和Safari

context.clearRect(0,0,w,h);    
context.fillStyle = 'rgba(0,0,0,1)';  
context.fillRect(0,0,w,h);  

让矩形充满
0 0 0 255
无论浏览器!


#12楼

如果您仅使用clearRect,如果您在表单中提交它,则可以提交,而不是提交清除,或者可以先将其清除,然后再上传空白图纸,因此需要添加一个函数开始时的preventDefault:

   function clearCanvas(canvas,ctx) {
        event.preventDefault();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }


<input type="button" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">

希望它可以帮助某人。


#13楼

一种简单但不太易读的方法是编写以下代码:

var canvas = document.getElementId('canvas');

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas

#14楼

Context.clearRect(starting width, starting height, ending width, ending height);

示例: context.clearRect(0, 0, canvas.width, canvas.height);


#15楼

如果要绘制线条,请确保不要忘记:

context.beginPath();

否则,行将不会被清除。


#16楼

这是2018年,仍然没有原生方法可以完全清除画布以进行重画。 clearRect() 不能完全清除画布。 非填充类型的图形不会清除(例如rect()

1.无论您如何绘画,都要完全清除画布:

context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.beginPath();

优点:保留strokeStyle,fillStyle等; 没有滞后;

缺点:如果在绘制任何内容之前已经在使用beginPath,则不需要

2.使用width / height hack:

context.canvas.width = context.canvas.width;

要么

context.canvas.height = context.canvas.height;

优点:与IE搭配使用缺点:将strokeStyle,fillStyle重置为黑色; ggy

我想知道为什么不存在本机解决方案。 实际上, clearRect()被视为单行解决方案,因为大多数用户在绘制任何新路径之前都会执行beginPath() 。 虽然beginPath仅在绘制线条时使用,而不是像rect().这样的封闭路径rect().

这就是为什么被接受的答案不能解决我的问题,而导致我浪费大量时间尝试其他黑客的原因。 诅咒你mozilla


#17楼

一种快速的方法是

canvas.width = canvas.width

知道它是如何工作的,但确实可以!


#18楼

这是我使用的,无论边界和矩阵转换如何:

function clearCanvas(canvas) {
  const ctx = canvas.getContext('2d');
  ctx.save();
  ctx.globalCompositeOperation = 'copy';
  ctx.strokeStyle = 'transparent';
  ctx.beginPath();
  ctx.lineTo(0, 0);
  ctx.stroke();
  ctx.restore();
}

基本上,它保存上下文的当前状态,并绘制一个透明像素,其copyglobalCompositeOperation 。 然后,还原以前的上下文状态。


#19楼

我总是用

cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);

#20楼

使用: context.clearRect(0, 0, canvas.width, canvas.height);

这是清除整个画布的最快,最具描述性的方法。

不要使用: canvas.width = canvas.width;

重置canvas.width重置所有画布状态(例如,转换,lineWidth,strokeStyle等),它非常慢(与clearRect相比),在所有浏览器中均不起作用,并且无法描述您实际尝试的操作去做。

处理变换后的坐标

如果你已经修改了变换矩阵(例如,使用scalerotatetranslate ),然后context.clearRect(0,0,canvas.width,canvas.height)可能不会清除画布的整个可见部分。

解决方案? 在清除画布之前,请重置转换矩阵:

// Store the current transformation matrix
context.save();

// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);

// Restore the transform
context.restore();

编辑:我刚刚进行了一些分析,并且(在Chrome中)清除300x150(默认大小)画布而不重置变换的速度大约快10%。 随着画布大小的增加,这种差异也会降低。

这已经相对无关紧要了,但是在大多数情况下,您将获得比清算还多的钱,而且我认为这种性能差异无关紧要。

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear

#21楼

其他人已经很好地回答了这个问题,但是如果上下文对象上的简单clear()方法对您有用(对我而言),这就是我根据以下答案使用的实现:

CanvasRenderingContext2D.prototype.clear = 
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }

    this.clearRect(0, 0, this.canvas.width, this.canvas.height);

    if (preserveTransform) {
      this.restore();
    }           
};

用法:

window.onload = function () {
  var canvas = document.getElementById('canvasId');
  var context = canvas.getContext('2d');

  // do some drawing
  context.clear();

  // do some more drawing
  context.setTransform(-1, 0, 0, 1, 200, 200);
  // do some drawing with the new transform
  context.clear(true);
  // draw more, still using the preserved transform
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值