[javascript] 다시 그리기 위해 캔버스를 지우는 방법

합성 작업을 실험하고 캔버스에 이미지를 그린 후 이미지를 제거하고 합성하려고합니다. 어떻게해야합니까?

다른 이미지를 다시 그리려면 캔버스를 지워야합니다. 이것은 한동안 계속 될 수 있으므로 매번 새로운 사각형을 그리는 것이 가장 효율적인 옵션이라고 생각하지 않습니다.



답변

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

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


답변

사용하다: context.clearRect(0, 0, canvas.width, canvas.height);

전체 캔버스를 지우는 가장 빠르고 설명적인 방법입니다.

사용하지 마세요: canvas.width = canvas.width;

재설정 canvas.width하면 모든 캔버스 상태 (예 : 변환, lineWidth, strokeStyle 등)가 재설정 되며 매우 느리고 (clearRect와 비교하여) 모든 브라우저에서 작동하지 않으며 실제로 수행하려는 작업을 설명하지 않습니다.

변환 된 좌표 다루기

당신은 변환 행렬을 수정 한 경우 (예를 들어, 사용 scale, rotate또는 translate다음) 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에서는) 변환을 재설정하지 않고 300×150 (기본 크기) 캔버스를 지우는 것이 약 10 % 빠릅니다. 캔버스 크기가 커질수록이 차이는 줄어 듭니다.

그것은 이미 상대적으로 중요하지 않지만 대부분의 경우 당신이 지우는 것보다 훨씬 더 많은 그림을 그릴 것입니다.이 성능 차이는 관련이 없다고 생각합니다.

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


답변

선을 그리는 경우 다음을 잊지 마십시오.

context.beginPath();

그렇지 않으면 줄이 지워지지 않습니다.


답변

다른 사람들은 이미 질문에 대답하는 훌륭한 일을했지만 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
};


답변

  • 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;
}


답변

이것은 2018이지만 여전히 다시 그리기 위해 캔버스를 완전히 지우는 기본 방법은 없습니다. 캔버스를 완전히 지우지 clearRect() 않습니다 . 비 채우기 형식의 도면은 밖으로 삭제되지 않습니다 (예. rect())

1. 그리는 방법에 관계없이 캔버스를 완전히 지우려면 :

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

장점 : strokeStyle, fillStyle 등을 유지합니다. 지연이 없습니다.

단점 : 무언가를 그리기 전에 이미 beginPath를 사용하는 경우 불필요

2. 너비 / 높이 핵 사용 :

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

또는

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

장점 : IE와 함께 작동 단점 : strokeStyle, fillStyle을 검은 색으로 재설정합니다. 게으른;

네이티브 솔루션이 존재하지 않는 이유가 궁금합니다. 실제로 clearRect()대부분의 사용자는 beginPath()새로운 경로를 그리기 전에 수행 하기 때문에 단일 회선 솔루션으로 간주됩니다 . beginPath는 선을 그릴 때만 사용되며 닫힌 경로는 아닙니다.rect().

이것이 받아 들여진 대답이 내 문제를 해결하지 못한 이유이며 다른 해킹을 시도하는 데 몇 시간을 낭비했습니다. 모질라 저주


답변

x, y 좌표와 캔버스의 높이와 너비를 전달하여 clearRect 메소드를 사용하십시오. ClearRect는 전체 캔버스를 다음과 같이 지 웁니다.

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