已被阅读 2578 次 | 文章分类:javascript | 2021-11-16 23:48
有时候需要标注模型,或者给模型表面添加一些文字信息;用以下方式可以实现
1 将文字绘制到canvas中,并将其用作Texture
效果如下
给正方体某个表面添加文字为例;如下创建一个正方体
// ---------------------------------------------------------------------
// 添加模型
// ---------------------------------------------------------------------
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);
其中正方体顶部表面,使用CanvasTexture作为材质,如下该材质可以用canvas或者img或者视频元素作为贴图,下面以canvas为例;
在canvas中绘制文本,可以通过filltext绘制文本,遍历可以实现换行的效果
// CanvasTexture
function getTextCanvas1(){
let texts=[{
name:"北京",
value:323
},{
name:"杭州",
value:121
},{
name:"南京",
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;
}
优点是可以绘制任意样式文字,缺点是canvas一旦生成,因为分辨率不再改变,所以在threejs中放大时会模糊
2 将文字绘制在平面,然后贴在几何体表面
这种方式适合较规范的几何体模型;仍然以上面正方体为例,跟第一种方式原理差不多,将文字绘制在一个透明几何平面上,然后把平面的位置设置在刚好覆盖正方体前表面;代码如下
function getTextCanvas2(){
//用canvas生成图片
let canvas = document.createElement("canvas");
let ctx = canvas.getContext('2d')
canvas.width = 300
canvas.height = 300
//制作矩形
ctx.fillStyle = "gray";
ctx.fillRect(0, 0, 300, 300)
//设置文字
ctx.fillStyle = "white";
ctx.font = 'normal 20px "楷体"'
ctx.fillText('这个平面将被贴在正方体前表面', 0, 20)
//生成图片
let url = canvas.toDataURL('image/png');
//将图片构建到纹理中
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();
效果:
可以看到没有贴到表面,需要调整z值为15.1, rect.position.set(0, 0, 15.1),看最后效果
但是平面的颜色将原本正方体颜色覆盖
将canvas矩形的颜色和材质颜色都设置为透明即可
//制作矩形
ctx.fillStyle = "transparent"; // 设为透明
//将图片构建到纹理中
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, // 设为透明
})
3 使用threejs提供的文字几何体接口
通过THREE.TextGeometry生成文字几何体。在一个立方体表面遍历添加一排文字,效果如下:
代码如下:
// ---------------------------------------------------------------------
// 添加文字模型
// ---------------------------------------------------------------------
let texts1=[
{
name:"北 京",
value:23
}
,{
name:"杭 州",
value:23
},
{
name:"南 京",
value:23
},
{
name:"南 京",
value:23
}
,{
name:"杭 州",
value:23
},
{
name:"南 京",
value:23
},
{
name:"南 京",
value:23
}
]
texts1.forEach((text,index)=>{
addTextGeometry(text,index);
})
// 添加文字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, // 字体格式
size: 13, // 字体大小
height: 1, // 字体深度
curveSegments: 11, // 曲线控制点数
bevelEnabled: true, // 斜角
bevelThickness: 0.1, // 斜角的深度
bevelSize: 1, // 斜角的大小
bevelSegments: 1 // 斜角段数
});
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是字体文件,如下 three提供了几中默认的字体格式,但是都支持英文,如果要添加中文文字,需要借助转换工具,将ttf的文字格式转换为json文件
转换很简单:首先下载字体文件 href="https://www.aigei.com/font/class/song_style/"
然后使用在线转换工具Facetype.js,转换为json文件后下载即可。也可以将该工具下载到本地,直接运行;
如果在使用过程中,报错找不到stylename的情况,可能是因为下载的ttf某些属性缺失,那么可以适当调整main.js代码,如下
QQ:3410192267 | 技术支持 微信:popstarqqsmall
Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号