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:
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