Several ways of adding text to threejs model

When adding text to geometry or imported model surfaces, you can use the following methods

1 draw text into canvas and use it as Texture

Add text to a surface of a cube as an example; Create a cube as follows

// ---------------------------------------------------------------------
// Add model
// ---------------------------------------------------------------------
var geometry = new THREE.BoxGeometry( 30,30, 30 );
var materials = [ 
    new THREE.MeshBasicMaterial( { color: 'blue' } ), // right
    new THREE.MeshBasicMaterial( { color: 'yellow' } ), // left
    new THREE.MeshBasicMaterial( { map: new THREE.CanvasTexture(getTextCanvas1()) } ), // top
    new THREE.MeshBasicMaterial( { color: 'black' } ), // bottom
    new THREE.MeshBasicMaterial( { color: 'green' } ), // back
    new THREE.MeshBasicMaterial( { color: 'red' } ) // front 
    ];
var cube = new THREE.Mesh( geometry, materials );
scene.add(cube);

For the top surface of the cube, canvas texture is used as the material. As follows, canvas or img or video elements can be used as the map for the material. Take canvas as an example below;

  Draw text in canvas. You can draw text through filltext. Traversal can achieve the effect of line feed

// CanvasTexture
function getTextCanvas1(){ 
    let texts=[{
        name:"Beijing",
        value:323
    },{
        name:"Hangzhou",
        value:121
    },{
        name:"Nanjing",
        value:56
    }]
    var width=512, height=256; 
    var canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#C3C3C3';
    ctx.fillRect(0, 0, width, height);
    ctx.font = 32+'px " bold';
    ctx.fillStyle = '#2891FF';
    texts.forEach((text,index)=>{
        ctx.fillText(`${text.name}:${text.value}`, 10, 32 * index + 30);
    }) 
    return canvas;
}

effect:

The advantage is that you can draw text of any style. The disadvantage is that once canvas is generated, the resolution will not change, so it will be blurred when zoomed in in threejs

2 attach a transparent surface to the surface of the geometry

         This method is suitable for more standard geometric model; Still take the above cube as an example, which is similar to the principle of the first method. Draw the text on a transparent geometric plane, and then set the position of the plane to just cover the front surface of the cube;

The code is as follows

function getTextCanvas2(){
 //Generate pictures with canvas
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext('2d')
  canvas.width = 300
  canvas.height = 300
  //Make rectangle
  ctx.fillStyle = "gray"; 
  ctx.fillRect(0, 0, 300, 300)
  //Set text
  ctx.fillStyle = "white";
  ctx.font = 'normal 20px "Regular script"'
  ctx.fillText('This plane will be attached to the front surface of the cube', 0, 20)

  //Generate picture
  let url = canvas.toDataURL('image/png');
  //Build pictures into textures
  let geometry1 = new THREE.PlaneGeometry(30, 30)
  let material1 = new THREE.MeshBasicMaterial({
    map: new THREE.TextureLoader().load(url),
    side: THREE.DoubleSide,
    opacity: 1
  })
  let rect = new THREE.Mesh(geometry1, material1)
  rect.position.set(0, 0, 25.1)
  scene.add(rect)
}
getTextCanvas2();

effect:  

It can be seen that it is not attached to the surface, and the z value needs to be adjusted to 15.1,   rect.position.set(0, 0, 15.1) to see the final effect

  However, the color of the plane will cover the original cube color

  Set the color and material color of the canvas rectangle to transparent

  //Make rectangle
  ctx.fillStyle = "transparent";  // Make transparent


  //Build pictures into textures
  let geometry1 = new THREE.PlaneGeometry(30, 30)
  let material1 = new THREE.MeshBasicMaterial({
    map: new THREE.TextureLoader().load(url),
    side: THREE.DoubleSide,
    opacity: 1,
    transparent: true, // Make transparent
  })

 

3 use the text geometry interface provided by threejs

Generate text geometry from THREE.TextGeometry. Add a row of text on the surface of a cube. The effect is as follows:

  The code is as follows:

// ---------------------------------------------------------------------
// Add text model
// ---------------------------------------------------------------------
let texts1=[
{
    name:"Beijing",
    value:23
}
,{
    name:"Hangzhou",
    value:23
},
{
    name:"Nanjing",
    value:23
},
{
    name:"Nanjing",
    value:23
} 
,{
    name:"Hangzhou",
    value:23
},
{
    name:"Nanjing",
    value:23
},
{
    name:"Nanjing",
    value:23
}

]
texts1.forEach((text,index)=>{
    addTextGeometry(text,index);
})


// Add text geometry
function addTextGeometry(text,index){
    var loader = new THREE.FontLoader(); 
    loader.load("/statics/fonts/chinese.json", function (res) { 
        var geometry = new THREE.TextGeometry(`${text.name}: ${text.value}`, {
            font: res,          // Font format
            size: 13,           // font size
            height: 1,          // Font depth
            curveSegments: 11,  // Curve control points
            bevelEnabled: true, // bevel angle
            bevelThickness: 0.1,  // Depth of bevel
            bevelSize: 1,       // The size of the bevel
            bevelSegments: 1    // Number of bevel segments
        });
        var mat = new THREE.MeshPhongMaterial({
            color: "white",
            opacity: 0.8,
            shininess: 1,
        });
        var mesh = new THREE.Mesh(geometry, mat);
        mesh.rotation.y=-Math.PI/2
        mesh.position.set(-151,150-40*index, 15.1);
        scene.add(mesh);
    }); 
}

  chinese.json is the font file. The following three provide several default font formats, but all support English. If you want to add Chinese text, you need to use the conversion tool to convert the text format of ttf into JSON file

  The conversion is simple:

      First download the font file Free download of song font library - aigei.com Chinese Chinese song, mini simple bold song, mini simple bold song, Hanyi super bold song, song bold font download, classic complex super song font download, sharp cloud font library large standard song font, song font in Wener advertisement, simsun font, sharp small standard song, Great Wall Extra Bold song font download, Hanyi newspaper song Jane font, great wall large standard song font, Lumen Heavy, Su Xinshi ancient printed song font download, Great Wall small label song font download, ruizi cloud font library small label song font, ruizi large label song, huakangya song font, ruizi medium long song font, great wall large label song font download, armored Ming Dynasty font, Microsoft simple label song font, Great Wall small labelhttps://www.aigei.com/font/class/song_style/

  Then use the online conversion tool Facetype.js , convert it into json file and download it. You can also download the tool locally and run it directly;

If an error is reported and the stylename cannot be found during use, it may be because some attributes of the downloaded ttf are missing. You can adjust the main.js code appropriately, as shown below

Tags: Javascript ThreeJS

Posted on Tue, 16 Nov 2021 10:50:28 -0500 by ternto333