4

描画するオブジェクトに「消去」機能を実装するのに問題があります。私はそのようにオブジェクトを描きます:

function draw_obj1(context) {
    context.lineTo(...)
    context.arc(...)
    //etc
}

そして、これらは私がキャンバス用に持っている画像の背景の上に描かれています(context.createPattern、fillStyle = patternなどを介して)。

したがって、上記の関数がさまざまなlineTo呼び出しを使用して三角形をトレースするとします。この描画を「消去」または「元に戻す」ために、私が持っていた1つの計画は、同じオブジェクトの「xor」バージョンをその上に再描画して、元に戻すことでした。これは、context.globalCompositeOperationを介して行います(https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.htmlを参照)。

これはほとんど機能しますが、最終結果が私の水色の背景に対して完全に空白にならない点が異なります。元の黒い線の三角形に対して、明るい灰色がかった三角形として表示されます。

編集-私が試した別のアイデアについて言及するのを忘れました。移動する必要のある領域で「clearRect」を実行すると、水色の背景にホワイトホールが作成されますが、これは良くありません。

では、描画した線/円弧を元に戻すにはどうすればよいですか?

乾杯

4

3 に答える 3

3

これは、Canvasコンテンツのみを使用しては不可能です。Canvas要素は、実際のキャンバスのように反応します。物事が描画されるため、それらはマージされ、全体像にバインドされます。

これは、ほとんどのグラフィックAPIでは、canvasが単なるバイトの配列であるためです。コンピュータは、現在のフレームを構成するオブジェクトを識別して区別する方法を単独で知ることはできません。

これを行うための最良の方法は、「シーングラフ」、グラフツリーのようなものを実装することです。次に、このグラフツリーにオブジェクトを追加し、キャンバス上に各オブジェクトを描画するための独自のアルゴリズムを構築できます。

履歴データ構造を使用して、シーングラフからオブジェクトを元に戻す/やり直すことができ、オブジェクトを小さなタイムスライス(ナノミリ秒)で再描画できます。

それはあなたの問題に対する全体論的な見方です。プログラムでグラフを処理する方法を知っていることを願っています。

詳細はこちら:HTML5 Canvasにundo機能を追加する方法は?

そしてここ:http ://www.abidibo.net/blog/2011/10/12/development-undo-and-redo-functionality-canvas/

于 2012-06-04T00:52:35.380 に答える
1

代わりに「キューの描画」を行う必要があります。つまり、キャンバス上で実行される一連の操作を配列に入れます。このアプローチの利点は、行うすべての動きが配列で追跡されることです。欠点は、変更に対応するためにキャンバス全体を再描画する必要があることです。

キャンバスアニメーションフレームワークは、ほとんどの場合これらを実行します。

簡単な表現は次のようなものです。

var drawingQueue = [
    {
        shape : 'rectangle',
        fill : 'red'
    },
    {
        shape : 'circle',
        fill : 'blue'
    },
    {
        shape : 'arc',
        fill : 'green'
    }
];

これdrawingQueueは、キャンバスに何を描画するかを指示するコマンドのコマンド/プロパティの配列です。この例では、このキューは赤い長方形、青い円、緑の弧を描きます。

たとえば、円を削除したい場合は、配列から円を削除して、キュー内のすべてを再描画します。これで、円は削除されます。元に戻すとしましょう。配列を使用しpop()て最後のアイテムを削除してから、円弧なしでキャンバスを再描画します。

ただし、開発を迅速化するために、代わりにフレームワークを使用することをお勧めします。キャンバス内の「要素」を簡単に追加および削除できるように、形状の内部追跡システムがあります。トップピックはKineticJSとFabricJSです。

于 2012-06-04T00:48:53.873 に答える
0
prev_comp = context.globalCompositeOperation
context.globalCompositeOperation = 'destination-out'
context.strokeStyle = "rgba(255, 255, 255, 1)"

/* Draw some "eraser" lines/shapes ..*/

context.globalCompositeOperation = prev_comp
于 2013-04-12T05:21:21.107 に答える