合成操作を試し、キャンバスに画像を描画した後、画像を削除して合成しようとしています。どうすればよいですか?
他の画像を再描画するには、キャンバスをクリアする必要があります。これはしばらく続く可能性があるので、毎回新しい長方形を描くことが最も効率的なオプションになるとは思いません。
合成操作を試し、キャンバスに画像を描画した後、画像を削除して合成しようとしています。どうすればよいですか?
他の画像を再描画するには、キャンバスをクリアする必要があります。これはしばらく続く可能性があるので、毎回新しい長方形を描くことが最も効率的なオプションになるとは思いません。
それcanvas
がcanvas要素またはOffscreenCanvas
オブジェクトであるとすると、
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 では) 変換をリセットせずに 300x150 (デフォルト サイズ) のキャンバスをクリアする方が約 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
};
context.clearRect ( x , y , w , h );
が、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;
}
キャンバスの x,y 座標と高さと幅を渡して clearRect メソッドを使用します。ClearRect はキャンバス全体を次のようにクリアします。
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ここにはたくさんの良い答えがあります。もう 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);
これは、境界とマトリックス変換に関係なく、私が使用するものです。
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
。次に、以前のコンテキスト状態を復元します。
私がテストしたすべてのブラウザーで、実際に fillRect を白または好きな色で埋めるのが最も速い方法であることがわかりました。私は非常に大きなモニターを使用しており、全画面表示モードでは clearRect は非常に遅くなりますが、fillRect は妥当です。
context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);
欠点は、キャンバスが透明でなくなることです。
最短の方法:
canvas.width += 0
Webkit では、幅を別の値に設定する必要があります。その後、初期値に戻すことができます
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で塗りつぶします。
最速の方法:
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
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);">
それが誰かを助けることを願っています。
これらはすべて、標準のキャンバスをクリアする方法の優れた例ですが、paperjs を使用している場合は、次のように動作します。
JavaScript でグローバル変数を定義します。
var clearCanvas = false;
PaperScript から次のように定義します。
function onFrame(event){
if(clearCanvas && project.activeLayer.hasChildren()){
project.activeLayer.removeChildren();
clearCanvas = false;
}
}
clearCanvas を true に設定すると、画面からすべてのアイテムがクリアされます。