前问提到了关于场景中给模型动态标注标签的一种方式 - dom,这篇文章将会讲述另一种方式 - texture纹理方式。
在场景中添加mesh的时候,我们可以给mesh添加想要的纹理材质,利用这个特性,就可以将需要展示的标签内容贴到mesh的面上,这样就可以实现利用纹理特性实现标签的构建,具体思路如下:
1.创建texture纹理材质:这里采用的是标签内容转化为图片的形式
// 利用canvas的属性,我们封装一个函数,根据数据的文字内容,创建一个canvas画布
function getTextToCanvas(text) {
let width = 512;
let height = 256;
let canvas = document.createElement('canvas');
canvas.width = width; // 设置画布的宽度
canvas.height = height; // 设置画布的高度
let contentStyle = canvas.getContext('2d'); // 设置画布内2D相关属性
contentStyle.fillStyle = '#ffffff';
contentStyle.fillRect(0, 0, width, height);
contentStyle.font = 50 + 'px " bold';
contentStyle.fillStyle = '#2891FF';
contentStyle.textAlign = 'center';
contentStyle.textBaseline = 'middle';
contentStyle.fillText(text, width / 2, height / 2);
return canvas;
}
2.利用步骤一的函数,得到我们需要的canvas内容:
let picUrl = getTextCanvas('我是标签').toDataURL("image/png"); // 将canvas转为图片格式
3.将图片作为材质,添加到模型上,并且给模型设置需要展示的坐标位置,这样一来,材质生成的标签就制作完毕了:
let geometry = new THREE.BoxGeometry(1, 8, 16);
let texture = new THREE.TextureLoader().load(picUrl);
let material = new THREE.MeshBasicMaterial({
map: texture
})
let lable = new THREE.Mesh(geometry, material);
lable.position.set(100, 100, 100);
lable.scale.set(5, 5, 5)
scene.add(lable);
根据上面的函数,我们可以做一个整体的封装,内容如下:
/**
* 添加标签:纹理方式
* @param {*} content : 标签文字内容
* @param {*} position :标签展示位置
*/
function createTextCanvas(content, position) {
let picUrl = getTextToCanvas(content).toDataURL("image/png");
let geometry = new THREE.BoxGeometry(1, 8, 16);
let texture = new THREE.TextureLoader().load(picUrl);
let material = new THREE.MeshBasicMaterial({
map: texture
})
let lable = new THREE.Mesh(geometry, material);
lable.position.set(position.x, position.y, position.z);
lable.scale.set(5, 5, 5)
scene.add(lable);
}
这种texture纹理的标签方式,对于样式具有一定的局限性,如果你想设置比较看好或者自定义任意样式的,可以采用前一篇文章说的dom方式。
欢迎大家提意见或者建议,相互学习!!!!!!