我使用javascript绘制到div中的canvas元素,包含在包装器中。 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或它的父母导致清除画布。关于如何避免清除画布的任何建议?我可以保留在其他地方绘制的画布并恢复它吗?
答案 0 :(得分:4)
无论你的javascript方法(jQuery,别的什么,或什么都没有),你可以通过不使用innerHTML来做到这一点。基本上,当你附加到innerHTML属性时,你会说“获取innerHTML的值,将它添加到这个新值(也许是canvas元素),然后将innerHTML设置为所有这些。换句话说,你不是'你真的附加了“就地”。你基本上是在添加你拥有的所有东西的新版本,并且因为画布没有用子元素绘制它的内容,所以它们不会被这种方法带来。
您应该使用DOM而不是使用innerHTML,将子节点作为节点而不是字符串附加到父节点。
答案 1 :(得分:0)
听起来这是jQuery的一个很好的用例。使用jquery,您可以将<canvas>
元素附加到任意容器中,并避免与“innerHtml”进行交互。
例如:
var myCanvas = $("<canvas>").appendTo("#container");
这样做是为id为“container”(你的div)的元素添加一个新的<canvas>
元素。 “#”是ids的css选择器。谷歌“css选择器”,因为这是一个相当广泛的主题。
myCanvas
变量现在是一个jQuery数组,其中包含对刚刚添加的画布的引用。 myCanvas[0]
将是您可以与之交互的实际DOM元素。
使用这种方法,您永远不需要更改div的“innerHtml”,因此永远不会触及/清除现有的画布。
答案 2 :(得分:0)
使用appendChild:
,而不是使用innerHtmldocument.getElementById('wrapper').appendChild(NewNodeHere);
答案 3 :(得分:-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);
}