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.
精彩评论