Search code examples
javascriptcanvasthree.jstexturessprite

Texture in threejs is not updating


I'm using the threejs editor as base for some threejs work. I'm trying to show some tooltips when the user hovers over certain elements. To achieve this I use a canvas which is rendered as texture on a sprite.

// create a canvas element
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 20px Arial";
context1.fillStyle = "rgba(0,0,0,0.95)";
context1.fillText('Hello, world!', 0, 20);

// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;

// use the texture as material
var spriteMaterial = new THREE.SpriteMaterial({
    map: texture1,
    useScreenCoordinates: false
});

// create the sprite and add it tho the scene
var sprite1 = new THREE.Sprite(spriteMaterial);
sprite1.scale.set(1000, 500, 1.0);
sprite1.position.set(50, 50, 0);
scene.add(sprite1);

var i = 0;
// change the canvas' content
setInterval(function () {
    context1.clearRect(0, 0, canvas1.width, canvas1.height);
    var message = 'test' + i++;
    context1.fillText(message, 4, 20);
    texture1.needsUpdate = true;
}, 1000)

"test0" is shown, but the sprite does not update. How to update the text on the sprite? Am I missing some cache invalidation here?

enter image description here


Solution

  • Why render the text box on your 3D canvas? It would be much better IMO to position your 2D html object by projecting the 3D object position in the 2D context of your page.

    The advantage is that there won't be any rendering performance decrease and you can use normal CSS/HTML styling for your info box.

    Check a great example on how you can do that here.

    And another one belonging to this stackoverflow answer. Works as simple as this:

    var proj = toScreenPosition(divObj, camera);
    
    divElem.style.left = proj.x + 'px';
    divElem.style.top = proj.y + 'px';
    

    But if you do some googling you can easily find more examples...

    Here is a fiddle to fool around with.