如何在三个js渲染画布中为画布添加结束标记?

时间:2016-05-20 06:25:25

标签: javascript canvas three.js webgl

三个js总是在页面上添加没有结束标记的canvas元素,背后是否有任何具体原因?

我想在这个canvas元素上添加一个结束标记。

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

为什么我希望这个结束标记可能很愚蠢,我试图使用

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

但是它返回null,所以在这里尝试了一些解决方案,没有工作并遇到this answer,所以我怀疑丢失的结束标记可能是个问题。

我真正想要做的是使用this将画布保存到图像中。

3 个答案:

答案 0 :(得分:3)

@ K3N的推荐答案是关于一点的:你的问题不是来自检查员中没有显示的</canvas>结束标记,而是来自你的试验,以从一个webgl的画布中获取2D上下文已经初始化了。

但是,

虽然在HTML5 some elements中确实不需要结束标记,但canvas

  

在text / html中标记遗漏:
  这两个标签都没有遗漏。

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

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

所以只是你的检查员,或者你的浏览器内部没有显示它,但你必须在你的标记中写
(实际上,如果我们谈论的是chrome,它只是检查员没有显示它,你可以通过调用canvas元素的outerHTML属性来看到它,结束标记就在那里。 )

对于解决方案,

您要做的是将画布导出为静态图像 为此,由于toBlob是一个HTMLCanvasElement的方法,你不需要当前的上下文,你只需要在你的问题中指出我们的the answer的最后一部分,以及小的调整:

正如this answer gman中所解释的那样,webgl canvas是双缓冲的,一旦浏览器可以清除绘图缓冲区,除非上下文是用{{1创建的preserveDrawingBuffer: true方法的参数 但是这个论点会对性能产生严重影响,最佳推荐方法是在同一个调用中调用getContext()方法。

由于它已经在那里得到了很好的解释,我不会在这个问题上做太多扩展,但请注意它也涉及toBlob()toDataURL()

答案 1 :(得分:2)

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

Three.js正在使用webgl上下文(如果可以)和画布,这意味着无法获得2d上下文。 specs do state如果获得了上下文,在这种情况下是webgl,那么如果请求2d,它应该:

  

返回null。

jsfiddle

table snapshot

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

答案 2 :(得分:1)

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

首先要说几点:

  1. “元素”选项卡可能会错误地忽略结束标记(我知道这是因为我有一个正确关闭的画布但是“元素”显示它已打开)。
  2. 您所引用的示例包含已损坏的标记,而非缺少标记。
  3. 当canvas标签关闭时,你的jsfiddle仍然失败 - 实验表明你不能为已经有webgl上下文的画布获得2d上下文,反之亦然(尽管你可以获得带有a的画布的2d上下文2d上下文,同样适用于webgl)。
  4. 一些建议:

    您可以使用getElementsByTagName('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