Reputation: 649
Since the webgl/opengl doesn't support text drawing, so it possible to draw 3D object using 3D context and text drawing using 2D context ?
Upvotes: 24
Views: 23824
Reputation: 1178
What I've been doing, whether I just need troubleshooting feedback or 2D text content on a 3D canvas, is just use CSS to put some HTML elements on top of the canvas.
You can make a canvas and a group of text fields share the same space, and ensure that the text fields are on top as follows:
HTML:
<div id="container">
<canvas id="canvas"></canvas>
<div id="controlsContainer">
<label>Mouse Coordinates</label>
<div>
<label for="xPos">X</label>
<span id="xPos"></span>
</div>
<div>
<label for="yPos">Y</label>
<span id="yPos"></span>
</div>
</div>
</div>
CSS:
canvas {
margin: 0px;
position: relative;
top: 0px;
left: 0px;
width: 100%;
}
#container {
position: relative;
}
#controlsContainer {
position: absolute;
left: 10px;
top: 10px;
z-index: 3;
}
#controlsContainer div {
padding-left: 8px;
}
#controlsContainer label {
color: white;
z-index: 4;
}
#controlsContainer span {
color: white;
z-index: 4;
}
The z-index
will ensure which elements are in front, and position: relative
for the container and position: absolute
, in coordination with the top
and left
for the controls will ensure that they share the same space.
I have been having very good luck with this, and the troubleshooting feedback is invaluable.
An example of the Javascript (ES6 in this case) is:
let xPos = document.getElementById("xPos");
let yPos = document.getElementById("yPos");
let x = event.clientX - containerDiv.offsetLeft -parseInt(window.getComputedStyle(pageBody).getPropertyValue("margin-left"));
let y = event.clientY - containerDiv.offsetTop - parseInt(window.getComputedStyle(pageBody).getPropertyValue("margin-top"));
xPos.innerText = x;
yPos.innerText = y;
which I've placed in a mousemove handler.
Upvotes: 4
Reputation: 2181
No, unfortunately not.
The HTML 5 spec says that if you call getContext
on a canvas element that is already in a different context mode and the two contexts are not compatible then return null
.
Unfortunately "webgl" and "2d" canvases are not compatible and thus you will get null
:
var canvas = document.getElementById('my-canvas');
var webgl = canvas.getContext("webgl"); // Get a 3D webgl context, returns a context
var twod = canvas.getContext("2d"); // Get a 2D context, returns null
Upvotes: 41
Reputation: 310917
As stated, you cannot do this.
However you can put one canvas on top of another and draw to them separately. I've done this before and it can work out quite well.
Upvotes: 21
Reputation: 185862
Create the text as a texture using canvas 2D, then render it in 3D. See here for a tutorial.
Upvotes: 6