如何在呈现 Canvas 的三个 js 中为 canvas 添加结束标记?

How to add closing tag for canvas in three js rendered Canvas?

三个js总是在页面添加canvas个没有结束标签的元素,有什么具体原因吗?

我想在此 canvas 元素上添加结束标记。

Example page ,检查页面显示,有些事情是这样的。

为什么我想要这个结束标记可能很愚蠢,我正在尝试使用

获取上下文
context = canvas.getContext('2d');

但它 returns null ,所以在这里尝试了一些解决方案,none 成功并遇到了 this answer,所以我怀疑缺少结束标记可能是个问题。

实际上我想做的是使用 this.

将 canvas 保存到图像中

canvas 结束标记不是您在这种情况下面临的问题。

Three.js 将 webgl 上下文(如果可以)与 canvas 一起使用,这意味着无法获得 2d 上下文。 specs do state 如果获得上下文,在本例中为 webgl,则如果请求 2d,则应:

Return null.

(jsfiddle)

这意味着您必须创建一个新的 canvas(不必插入 DOM),然后从中获取 2D 上下文。然后在您的 2D 上下文中使用 drawImage(),使用 webgl canvas 元素作为图像源进入您的新 canvas。然后你应该能够从中提取一个bitmap/image。

@K3N 赞成的答案有一点是正确的:你的问题不是来自检查器中未显示的 </canvas> 结束标记,而是来自你从 [=61 中获取 2D 上下文的试验=] 其中一个 webgl 已经被初始化。


但是,

虽然 HTML5 some elements don't need a closing tag, for canvas

确实如此

Tag omission in text/html:
      Neither tag is omissible.

这是对other fiddle的一个小反证,因为是的,<script>内容应该在遇到时直接执行,现代浏览器使canvas元素可用DOM 在他们遇到结束标记之前,这些浏览器能够执行这个简单的脚本,(IE9 不会)但这肯定是你想要避免的事情:

canvas{border: 1px solid}
<canvas>
<p>I'm not there</p>

所以这只是你的检查器,或者可能在你的浏览器内部没有显示它,但是你必须把它写在你的标记。
(实际上,如果我们说的是chrome,只是inspector没有显示,你可以调用outerHTML 属性 canvas 元素,结束标记将在那里。)

对于解决方案,

您要做的是将 canvas 导出为静态图像。
为此,由于 toBlob is an HTMLCanvasElement's method, you don't need the current context , you only need the last part of the answer 你在你的问题中指出了我们,并且进行了小的调整:

正如在 by gman 中所解释的那样,webgl canvas 是双缓冲的,绘图缓冲区将在浏览器可以清除的情况下尽快清除,除非上下文是使用 preserveDrawingBuffer: true getContext() 方法的参数。
但是这个参数会对性能产生严重影响,最好的推荐方法是在与渲染相同的调用中同步调用 toBlob() 方法。

因为那里已经很好地解释了,所以我不会在这个主题上展开太多,但请注意它也涉及 toDataURL()some2dCanvas.drawImage(yourWebglCanvas,x,y)

我一直在尝试做类似的事情。

首先几点:

  1. Elements 选项卡可能会错误地省略结束标记(我知道这是因为我有一个正确关闭的 canvas 但 Elements 显示它是打开的)。
  2. 您提到的示例有一个 损坏的 标签,而不是 缺失的 标签。
  3. 当 canvas 标记关闭时,您的 jsfiddle 仍然失败 - 实验表明您无法为已经具有 webgl 上下文的 canvas 获取 2d 上下文,反之亦然(尽管您可以为具有 2d 上下文的 canvas 获取 2d 上下文,对于 webgl 也是如此。

一些建议:

您可以使用 getElementsByTagName('canvas')。如果你只有一个 canvas,问题就解决了,否则只需搜索所需的 canvas.

的结果

或者,您可以尝试以下方法(改编自 How to Copy Contents of One Canvas to Another Canvas Locally):

//Append the renderer to a div
div.appendChild(renderer.domElement);
div.id = "renderTarget";

// first child element of div will be canvas
var canvas = div.firstElementChild;

// draw webgl canvas to 2d canvas
var destCtx = document.getElementById("copy").getContext('2d');
destCtx.canvas.height = canvas.height;
destCtx.canvas.width = canvas.width;
destCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height);

// now do what you like with the 2d canvas destCtx

HTH