@K3N的答案中提到的一点是正确的:您的问题不是来自检查器中未显示的</canvas>
闭合标签,而是因为您试图从已经初始化了webgl的画布中获取2D上下文。
虽然在HTML5中某些元素不需要闭合标签,但对于画布(canvas)来说:
在text/html中标签不能省略:
两个标签都不能省略。
这里有一个小的反例另一个代码片段,因为是的,<script>
内容应该在遇到时直接执行,并且现代浏览器在遇到结束标签之前就会将canvas元素放入DOM中,这些浏览器能够执行这个简单的脚本(IE9不能),但这绝对是你要避免的事情:
canvas{border: 1px solid}
<canvas>
<p>I'm not there</p>
所以只是你的检查器,或者可能是你的浏览器内部没有显示它,但是你必须在你的标记中写下它。
(实际上,如果我们谈论的是Chrome,只有检查器不显示它,您可以通过调用canvas元素的outerHTML
属性来看到它,关闭标签将会出现。)
你想做的是将canvas导出为静态图像。
对于这个问题,由于toBlob
是HTMLCanvasElement的方法,你不需要当前的上下文,你只需要最后一部分答案中的代码,并进行小的调整:
getContext()
方法的preserveDrawingBuffer: true
参数创建的。toBlob()
方法。
由于这已经在此答案中得到很好的解释,因此我不会在这个主题上过多扩展,但请注意,它也涉及toDataURL()
和some2dCanvas.drawImage(yourWebglCanvas,x,y)
。
toBlob
和toDataURL
是HTMLCanvasElement的方法,并不特定于某种类型的上下文。此外,如果上下文没有使用getContext()
方法的preserveDrawingBuffer: true
参数创建,并且在渲染循环之后调用了drawImage
(也适用于toXXX
),则只会得到一张黑色图片。有关更多信息,请参见此答案。 - Kaiido我刚刚也在尝试做类似的事情。
首先有几点需要注意:
一些建议:
你可以使用getElementsByTagName('canvas')。如果只有一个canvas,问题解决了,否则只需搜索所需的canvas结果即可。
或者,你可以尝试以下方法(改编自如何将一个Canvas的内容复制到另一个Canvas):
//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