【问题标题】:Create 2d context *without* canvas创建 2d 上下文 *无 * 画布
【发布时间】:2011-04-22 23:07:39
【问题描述】:

我目前正在寻找一种方法来创建画布 2d 渲染上下文,而实际上页面上没有画布元素。我可以动态创建一个画布元素并将其隐藏,但是我又不想在任何时候直接向用户显示图像,因此在页面中实际上没有画布元素。所以我基本上是在寻找类似的东西

var image = new Image( );

但仅适用于 canvas 2d 渲染上下文(伪代码)

var context = new 2dContext( );

有这样的功能吗?我找不到类似的东西。调用

var context = new CanvasRenderingContext2D( );

这是 HTML5 规范的渲染上下文接口的名称,只是在 Firefox 中给我带来了尴尬的错误:

uncaught exception: [Exception... "Cannot convert WrappedNative to function" nsresult: "0x8057000d (NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN)" location: "JS frame :: http://localhost/ :: <TOP_LEVEL> :: line 25" data: no]

【问题讨论】:

  • 那么上下文的意义何在?可能有更好的方法可以在不使用上下文的情况下完成您想做的事情。是什么让您决定使用上下文?需要什么?
  • 我正在开发一个基于浏览器的棋盘游戏实现,它使用画布来绘制棋盘。一个重要的特点是棋盘实际上比你的视口大,所以你必须能够平移。平移需要非常高的刷新率才能看起来流畅,而当前的 ECMA Script + Canvas 实现根本无法提供这种性能。因此,我打算使用一种缓冲方法,将整个板子绘制到一个不可见的上下文中,每当发生变化并将该上下文的部分剪辑到视口画布中以(显着地)提高刷新率。
  • 如果您不需要任何花哨/复杂的东西,您通常可以摆脱使用/滥用 HTML 而不是寻找 SVG 解决方案或其他任何东西除了canvas 之外。
  • 如果您将需求分解为可视片段并适当定位它们会有所帮助吗?
  • 好吧,既然该项目的目标之一是更好地进入 Javascript,尤其是 Canvas,我想离开画布作为一种技术是没有意义的 ;) 此外,实际上或多或少有些“花哨” /complex” 的事情正在发生,例如。使用插值贝塞尔曲线(-> 运动箭头)绘制寻路结果,如果没有动态绘图(画布、SVG 等),我将无法做到这一点。我当然可以使用隐藏的画布来获取缓冲上下文,事实上它确实可以工作,也很好,但我只是觉得“这不好,它不应该是必要的”。

标签: javascript html canvas


【解决方案1】:

可以使用画布而不在页面上显示它。您可以执行以下操作:

// Create a canvas element
var canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 400;

// Get the drawing context
var ctx = canvas.getContext('2d');

// Then you can do stuff, e.g.:
ctx.fillStyle = '#f00';
ctx.fillRect(20,10,80,50);

一旦你使用了画布,你当然可以将它添加到文档中

var element = document.getElementById('canvas_container');
element.appendChild(canvas);

或者您可以从中制作图像:

var new_image_url = canvas.toDataURL();
var img = document.createElement('img');
img.src = new_image_url;

或者您可以通过以下方式访问画布数据:

var image_data = ctx.getImageData(0, 0, canvas.width, canvas.height);
var rgba_byte_array = image_data.data;
rgba_byte_array[0];  // red value for first pixel (top left) in the canvas

【讨论】:

  • 感谢您的回答。我知道这种方法,但觉得这不是我想要的。可能这是我最好的选择。
  • 不幸的是,这在 WebWorkers 中不起作用,这是我个人的需要。他们无权访问 DOM,但我想在后台线程上进行一些绘图操作。
【解决方案2】:

有趣的是,如果您创建一个画布对象并将其上下文存储在一个变量中,则该变量有自己的指向画布对象的指针。由于您不能在没有画布的情况下使用 getContext("2d"),因此您最好只有一个画布指针。如果你像我一样讨厌有两个对同一个对象的引用,你可以这样做:

原文:

var canvas=document.createElement("canvas");
var context=canvas.getContext("2d");

alert(Boolean(context.canvas==canvas));// true.

我在说什么:

var context=document.createElement("canvas").getContext("2d");

alert(context.canvas);// The canvas object.

现在您可以通过上下文变量来完成所有重要的画布内容。毕竟,上下文比 canvas 变量更频繁地被访问。当您确实需要它时,只需通过上下文引用它:

context.canvas.width=320;
context.canvas.height=320;
document.body.appendChild(context.canvas);

如果您不想打扰画布,只需将变量放在一边,反正您也不想使用它。

【讨论】:

    【解决方案3】:

    怎么样:OffscreenCanvas()?

    答案可能是否定的,因为目前只有 Firefox 44.0+ 支持。

    var offscreen = new OffscreenCanvas(256, 256);
    

    https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas

    https://html.spec.whatwg.org/multipage/scripting.html#the-offscreencanvas-interface

    (在此处添加以供参考,因为这很可能是规范中的新问题,因为这个问题是 6 年前提出的!希望会被更广泛地采用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2011-08-17
      相关资源
      最近更新 更多