开发者

Switch canvas context

Assuming that I have a WebGL canvas (by calling getContext("experimental-webgl")).

Is there any way to switch context later for using a "2d" one ?

The goal of such thing would be to display a debug BSOD-like when an error happening during rendering.

If it's not possible, then :

  • Can I embed an html element over a canvas, and force this element to have exactly the same same that the canvas (even if this last is resized) ?
  • Can I replace an dom node, and update every reference about the old one to reflect the changement ?

[edit] This is my current minimal call code. Canvas is a DOM node containing a canvas which is filled by WebGL API, and callback is a function which process a single frame.

function failure(cvs, e) {
    var ctx = cvs.getContext('2d'); // Fail here, returns `null' if cvs.getContext('webgl') has been called
    ctx.fillStyle = 'rgb(0, 0, 0)';
    ctx.fillRect(0, 0, cvs.width, cvs.height);
    ctx.fillStyle = 'rgb(255, 255, 255)';
    ctx.font = 'bold 12px sans-serif';
    ctx.fillText(e.toString(), 0, 0);
}

function foobar(canvas, callback) {
    try {
        callback();
    } catch (e) {
        failure(canvas, e);
        throw e;
    } finally {
        requestAnimatio开发者_JS百科nFrame(arguments.callee);
    }
}


The short answer is pretty much no, according to the spec.

Every canvas has what is called a primary context. This is the first context that is invoked on a canvas. Making a non-primary context on a canvas might do some things on different browsers but I would never, ever depend on it.

I would instead have a second canvas that is overlaid over the first and maintains the same width and height attributes. I would then hide one and unhide the other (or just unhide the 2D one when you want it seen).

OR just use a PNG for simplicity's sake., centered inside of a DIV that also holds the canvas. In other words:

Div container has black background and holds:

  • PNG (centered)
  • 3D Canvas

Then when you want the error png to be displayed you just hide the 3D canvas (and optionally unhide the PNG)


Rather than have two canvases overlaying, the solution I went with was to replace the existing canvas with a clone of itself.

var newCvs = cvs.cloneNode(false);
cvs.parentNode.replaceChild(newCvs, cvs);
cvs = newCvs;

All the properties of the original canvas will be retained but the context will be freed up to allocate as you wish.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜