3

私はjavascriptを使用して、ラッパー内に含まれるdiv内のcanvas要素に描画しています。キャンバスとそのdivは、ラッパーのinnerHTMLに追加することで動的に生成されます。目標は、無限の数のキャンバスを生成できるようにすることです。

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
     <!-- infinite # of container divs & canvases -->
</div>

ただし、ラッパーのinnerHTMLに新しいdivとcanvasを追加すると、前のキャンバスに描画されたものはすべて失われます。

ページの他の場所、コンテナの外部のdiv、またはコンテナの子に新しいキャンバスを追加した場合:

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
</div>
<div id="wrapper2">
     <!-- newly inserted canvas: -->
     <div id="container"><canvas></canvas></div>
</div>

また:

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
     <div id="wrapperChild">
          <!-- newly inserted canvas: -->
          <div id="container"><canvas></canvas></div>
     </div>
</div>

その後、前のキャンバスが保持されます。

ラッパーまたはその親のinnerHTMLを変更すると、キャンバスがクリアされます。キャンバスのクリアを回避する方法について何かアドバイスはありますか?キャンバスに描画されたものを他の場所に保存して復元できますか?

4

4 に答える 4

4

javascriptのアプローチ(jQuery、他の何か、または何もない)に関係なく、innerHTMLを使用しないことでこれを行うことができます。基本的に、innerHTMLプロパティに追加すると、「innerHTMLの値を取得し、それをこの新しい値(おそらく、canvas要素)に追加してから、innerHTMLをそのすべてに設定します。つまり、あなたはそうではありません」 t実際に「インプレース」を追加します。基本的に、持っているすべてのものの新しいバージョンを追加します。キャンバスは子要素を使用してコンテンツを描画しないため、このメソッドでそれらを引き継ぐことはありません。

innerHTMLを使用する代わりに、DOMを使用して、文字列ではなくノードとして子を親に追加する必要があります。

于 2012-08-23T19:16:09.110 に答える
0

このように聞こえるのは、jQueryの良いユースケースです。jqueryを使用すると、<canvas>要素を任意のコンテナーに追加して、「innerHtml」と対話する必要をなくすことができます。

例えば:

var myCanvas = $("<canvas>").appendTo("#container");

<canvas>これは、IDが「container」(div)である要素に新しい要素を追加することです。「#」はIDのcssセレクターです。グーグルの「cssセレクター」、それはかなり広いトピックだからです。

これで、myCanvas変数は、追加したキャンバスへの参照を含むjQuery配列になります。myCanvas[0]対話できる実際のDOM要素になります。

このアプローチを使用すると、divの「innerHtml」を変更する必要がなくなるため、既存のキャンバスが変更/クリアされることはありません。

于 2012-08-23T19:11:35.187 に答える
0

innerHtmlを使用する代わりに、appendChildを使用します。

document.getElementById('wrapper').appendChild(NewNodeHere);
于 2012-08-23T19:15:27.230 に答える
-2

図形の描画に関するSimonのチュートリアルを確認してください。 http://simonsarris.com/project/canvasdemo/shapes.html

図形のすべてのプロパティと位置は、オブジェクト配列内に格納されます。(図形をクリックする)などのイベントが発生すると、キャンバスの状態が変化し(この場合、図形がドラッグされます)、マウスの位置が変わるたびに、新しい座標とプロパティを使用してキャンバスが再描画されます。

これで、図形、画像、テキストオブジェクトも使用する場合、それらのプロパティをオブジェクト配列に格納することもできます。このようにして、配列を複数回繰り返すだけで、同じ方法で複数のキャンバスに同じ形状を描くことができます。

したがって、新しいキャンバスを動的に追加する場合は、前のコンテキストを簡単に再描画できます。

これは、Simonのチュートリアルの関連コードです。

長方形の形状を定義します(コンストラクター)

function Shape(x, y, w, h, fill) {
  this.x = x || 0;
  this.y = y || 0;
  this.w = w || 1;
  this.h = h || 1;
  this.fill = fill || '#AAAAAA';
}

この図形を特定のコンテキストに描画しますShape.prototype.draw=function(ctx){ctx.fillStyle = this.fill; ctx.fillRect(this.x、this.y、this.w、this.h); }

配列に新しい形状を追加する

CanvasState.prototype.addShape = function(shape) {
  this.shapes.push(shape);
  this.valid = false;
}

配列を反復処理し、それに応じてすべての形状を描画します

var l = shapes.length;
for (var i = 0; i < l; i++) {
  var shape = shapes[i];
  // We can skip the drawing of elements that have moved off the screen:
  if (shape.x > this.width || shape.y > this.height ||
      shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
  shapes[i].draw(ctx);
}
于 2012-08-23T19:24:36.680 に答える