1175

合成操作を試し、キャンバスに画像を描画した後、画像を削除して合成しようとしています。どうすればよいですか?

他の画像を再描画するには、キャンバスをクリアする必要があります。これはしばらく続く可能性があるので、毎回新しい長方形を描くことが最も効率的なオプションになるとは思いません。

4

25 に答える 25

1544

それcanvasがcanvas要素またはOffscreenCanvasオブジェクトであるとすると、

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

context.clearRect(0, 0, canvas.width, canvas.height);
于 2010-01-26T20:52:18.097 に答える
772

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

これは、キャンバス全体をクリアする最も速くてわかりやすい方法です。

使用禁止:canvas.width = canvas.width;

リセットcanvas.widthすると、すべてのキャンバスの状態 (変換、lineWidth、strokeStyle など) がリセットされます。(clearRect と比較して) 非常に遅く、すべてのブラウザーで機能するわけではなく、実際に何をしようとしているのかが説明されていません。

変換された座標の処理

変換マトリックスを変更した場合 (例: scalerotate、またはを使用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 では) 変換をリセットせずに 300x150 (デフォルト サイズ) のキャンバスをクリアする方が約 10% 高速です。キャンバスのサイズが大きくなると、この差は小さくなります。

それはすでに比較的重要ではありませんが、ほとんどの場合、クリアしているよりもかなり多くの描画を行っているため、このパフォーマンスの違いは無関係であると考えています.

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
于 2011-07-17T05:06:28.823 に答える
250

線を引く場合は、次のことを忘れないようにしてください。

context.beginPath();

そうしないと、行がクリアされません。

于 2011-01-13T07:12:09.707 に答える
125

他の人はすでに質問に答える素晴らしい仕事を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
};
于 2012-03-15T15:05:13.993 に答える
36
  • @ Pentium10で提案されているように、Chromeは次のようにうまく反応しますcontext.clearRect ( x , y , w , h );が、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;
}
于 2010-11-03T09:48:48.517 に答える
21

キャンバスの x,y 座標と高さと幅を渡して clearRect メソッドを使用します。ClearRect はキャンバス全体を次のようにクリアします。

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
于 2013-11-13T06:08:52.037 に答える
14

ここにはたくさんの良い答えがあります。もう 1 つの注意点は、キャンバスを部分的にクリアするのが楽しい場合があるということです。つまり、前のイメージを完全に消去するのではなく、「フェード アウト」します。これにより、素晴らしいトレイル効果が得られます。

それは簡単です。背景色が白だとします。

// 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);
于 2012-05-04T04:36:42.540 に答える
9

これは、境界とマトリックス変換に関係なく、私が使用するものです。

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();
}

基本的に、コンテキストの現在の状態を保存し、 as で透明なピクセルを描画しcopyますglobalCompositeOperation。次に、以前のコンテキスト状態を復元します。

于 2018-05-28T15:14:28.903 に答える
6

私がテストしたすべてのブラウザーで、実際に fillRect を白または好きな色で埋めるのが最も速い方法であることがわかりました。私は非常に大きなモニターを使用しており、全画面表示モードでは clearRect は非常に遅くなりますが、fillRect は妥当です。

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

欠点は、キャンバスが透明でなくなることです。

于 2013-03-25T22:29:13.087 に答える
6

最短の方法:

canvas.width += 0
于 2020-01-22T18:06:48.430 に答える
4

Webkit では、幅を別の値に設定する必要があります。その後、初期値に戻すことができます

于 2010-08-02T04:50:02.883 に答える
2
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で塗りつぶします。

于 2016-12-12T09:53:44.530 に答える
1

最速の方法:

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
于 2012-08-13T18:32:05.220 に答える
1

clearRect のみを使用する場合、図面を送信するフォームに含まれている場合は、クリアの代わりに送信を取得するか、最初にクリアしてから void 図面をアップロードすることができるため、追加する必要があります関数の開始時の 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);">

それが誰かを助けることを願っています。

于 2017-01-10T18:14:56.580 に答える
0

これらはすべて、標準のキャンバスをクリアする方法の優れた例ですが、paperjs を使用している場合は、次のように動作します。

JavaScript でグローバル変数を定義します。

var clearCanvas = false;

PaperScript から次のように定義します。

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

clearCanvas を true に設定すると、画面からすべてのアイテムがクリアされます。

于 2012-04-12T15:58:27.667 に答える