Hey guys,
I’m currently setting up some simple text output for a main menu. Each button has a title and little blurb. The titles work great since they are one line of text. The blurbs however vary due to their length. I have a texture set up where the text is output to, and am trying to have it so the blurbs can be multi-line.
Passing in \n doesn’t seem to do anything.
Here is how I am handling the text elements:
function UpdateMainUITextContext(title, body){
if(mainUITextMesh != null){
scene.remove(mainUITextMesh);
}
const canvasSize = 512;
var canvas = document.createElement('canvas');
canvas.width = canvas.height = canvasSize;
mainUITextContext = canvas.getContext('2d');
mainUITextContext.fillStyle = 'black';// "rgba(255, 0, 0, 0.95)";
mainUITextContext.font = "Bold 60px Arial";
mainUITextContext.textAlign = 'center';
mainUITextContext.textBaseline = 'middle';
//mainUITextContext.fillRect(0, 0, canvasSize, canvasSize); //used this to see where i was placing text
mainUITextContext.fillText(title, canvas.width / 2, 150, canvas.width);
mainUITextContext.font = "Normal 60px Arial";
mainUITextContext.fillText(body, canvas.width / 2, canvas.height / 2, canvas.width);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial( {
map: texture,
side: THREE.DoubleSide,
depthWrite: false,
depthTest: false,
color: 0xff0000
});
material1.transparent = true;
mainUITextMesh = new THREE.Mesh(
new THREE.PlaneGeometry(4.5, 4.5),
material1
);
mainUITextMesh.renderOrder = 11;
mainUITextMesh.position.set(0,0,0);
scene.add(mainUITextMesh);
}
Appreciate any assistance guys!
So, TIL - fillText doesn’t support multiline text output. However, you can just stack your fillText calls. So, since this is just a PoC - I broke the blurbs of text into lines, stuffed those into my custom object as an array, then just step over that with a for loop which hits fillText for each element.
Hacky but gets the job done for now!
I might have missed something in the code - but it seems like you’re just painting the text on a transparent CanvasTexture and apply it to a plane to get a flat, transparent text?
If that’s the case - maybe Troika would be helpful? It renders flat text using fancy, performant maths and also supports multilines out-of-the-box.
Awesome! I’m checking this out now it looks sweet. My project is three-js and vanilla JS otherwise. Any idea how I can use this? I’m pretty new to JS - but I know I can’t import anything and have to put the src in my index.html but not sure which scripts it needs to work. Thanks!
Yeah, it seems a bit hidden - you can access and download built modules on unpkg (for both troika-three-text and it’s troika-dependencies.)
Awesome! Thanks so much! Is there a specific part of my project that these scripts should live in? I made a custom folder called Text in my JS folder and it’s breaking hard currently lol
Uncaught TypeError: Failed to resolve module specifier “three”. Relative references must start with either “/”, “./”, or “…/”.
Uncaught TypeError: Cannot read property ‘defineWorkerModule’ of undefined
at troika-three-text.umd.js:1053
at troika-three-text.umd.js:4
at troika-three-text.umd.js:5
Uncaught TypeError: Cannot read property ‘defineWorkerModule’ of undefined
at troika-three-text.umd.min.js:20
at troika-three-text.umd.min.js:10
at troika-three-text.umd.min.js:10
Then this is from my index.html
<script type="module" src="js/text/troika-three-text.esm.js"></script>
<script type="module" src="js/text/troika-three-text.umd.js"></script>
<script type="module" src="js/text/troika-three-text.umd.min.js"></script>