【问题标题】:How to add closing tag for canvas in three js rendered Canvas?如何在三个js渲染的画布中为画布添加结束标签?
【发布时间】:2016-09-17 06:53:40
【问题描述】:

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

我想在这个画布元素上添加一个结束标签。

Example page ,检查页面显示,类似这样的东西。

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

context = canvas.getContext('2d');

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

我实际上想要做的是使用this 将画布保存到图像中。

【问题讨论】:

    标签: javascript canvas three.js webgl


    【解决方案1】:

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

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

    返回空值。

    (jsfiddle)

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

    【讨论】:

    • 嗯...如果 OP 只想要他的 webgl 上下文中的 Blob,为什么要使用 2d 上下文? toBlobtoDataURL 是 HTMLCanvasElement 的方法,并不特定于某种上下文。此外,如果没有使用getContext() 方法的preserveDrawingBuffer: true 参数创建上下文,并且在渲染循环之后调用了drawImage(也适用于toXXX),您只会得到一个黑色图像。请参阅此answer 了解更多信息。
    • @K3N 感谢您的宝贵时间,我会尝试更新您。 @Kaiido 我会检查这些答案:)
    • 优秀的答案 K3N。我有一个screenshot example,你可能会感兴趣 JAYV
    【解决方案2】:

    @K3N's upvoted answer's upvoted answer's right about one point: 你的问题不是来自检查器中未显示的</canvas> 结束标签,而是来自你尝试从已经有 webgl 的画布中获取 2D 上下文初始化。


    但是,

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

    文本/html 中的标记遗漏:
    两个标签都不能省略。

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

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

    所以它只是您的检查器,或者可能是您的浏览器内部没有显示它,但是您必须在标记中编写它
    (其实如果说chrome的话,只是inspector不显示,调用canvas元素的outerHTML属性可以看到,结束标签就在那里。)

    对于解决方案,

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

    正如 gmanthis answer 中所解释的那样,webgl 画布是双缓冲的,并且绘图缓冲区将在浏览器可以清除时立即清除,除非上下文是使用 @ 的 preserveDrawingBuffer: true 参数创建的987654335@方法。
    但是这个参数会对性能产生严重影响,最好的推荐方法是在与渲染相同的调用中同步调用toBlob() 方法。

    由于那里已经很好地解释了,我不会在这个主题上过多地扩展,但请注意它也涉及toDataURL()some2dCanvas.drawImage(yourWebglCanvas,x,y)

    【讨论】:

    • 是的,我更(也是?)关注检查员显然对标签所做的事情,但你是对的,无论如何都是必需的(我半睡半醒的答案已更新)。我回答的第二部分侧重于在使用 webgl 时如何获取 2D 上下文。
    【解决方案3】:

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

    先说几点:

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

    一些建议:

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

    【讨论】:

      猜你喜欢
      • 2013-02-18
      • 2013-03-25
      • 2021-06-04
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2017-12-18
      • 2015-10-23
      • 1970-01-01
      相关资源
      最近更新 更多