3

我正在使用 javascript 绘制到包含在包装器中的 div 内的画布元素。画布及其 div 是通过添加到包装器的 innerHTML 来动态生成的。目标是允许生成无限数量的画布

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

但是,当我将新的 div 和画布添加到包装器的 innerHTML 时,绘制到前一个画布的任何内容都会丢失。

如果我在页面的其他地方添加新的画布,添加到容器外部的 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

不要使用 innerHtml,而是使用 appendChild:

document.getElementById('wrapper').appendChild(NewNodeHere);
于 2012-08-23T19:15:27.230 回答
0

听起来这是jQuery的一个很好的用例。使用 jquery,您可以将<canvas>元素附加到任意容器中,并且避免与“innerHtml”交互。

例如:

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

这样做是向 id 为“容器”(您的 div)的元素添加一个新<canvas>元素。“#”是 ids 的 css 选择器。谷歌“css 选择器”,因为这是一个相当广泛的话题。

myCanvas变量现在是一个 jQuery 数组,其中包含对您刚刚添加的画布的引用。myCanvas[0]将是您可以与之交互的实际 DOM 元素。

使用这种方法,您将永远不需要更改 div 的“innerHtml”,因此现有的画布将永远不会被触摸/清除。

于 2012-08-23T19:11:35.187 回答
-2

查看西蒙关于绘制形状的教程。 http://simonsarris.com/project/canvasdemo/shapes.html

形状的所有属性和位置都存储在对象数组中。当像(单击形状)这样的事件发生时,画布的状态会发生变化(在这种情况下,形状正在被拖动),并且对于鼠标位置的每次变化,画布都会使用新的坐标和属性重新绘制。

现在,如果您还使用形状、图像、文本对象,您也可以将它们的属性存储在对象数组中。这样,您只需多次遍历数组,就可以以相同的方式在多个画布上绘制相同的形状。

因此,当您动态添加新的画布时,您可以简单地重绘之前的上下文。

这是西蒙教程中的相关代码:

您定义一个矩形形状(构造函数)

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 回答