Step1:下载字体
ThreeJS原生字库是不带中文的,如果输出中文会显示乱码。解决这个问题第一步是下载中文字体。网上有很多免费的字体如阿里巴巴普惠体、思源系列等等,可以自行去网上搜索相关资源,同样为了节省大家时间,作者将相关资源上传到网盘供大家下载:
链接:https://pan.baidu.com/s/1_z4MHG8UeIb7WOpuY2pu_Q提取码: 37kt
Step2:转换字体
将ttf格式的字体文件转换成json格式或者js格式,可以通过http://gero3.github.io/facetype.js/这个网站直接转换。下面提供下阿里普惠体转换成facetype格式链接。
链接:https://pan.baidu.com/s/1lSJjXaYbTDDqmAyJvD-kww提取码: pg8u
Step3:加载字体
利用ThreeJS的FontLoader进行加载并构造ThreeJS的Font类,一般我们会在应用中创建一个类用来处理字体相关的操作。由于比较简单,直接贴代码:
/*
* @Description: 字体
* @Version: 1.0
* @Author: CatKnight
* @Date: 2020-11-12 14:11:15
* @LastEditors: CatKnight
* @LastEditTime: 2020-11-24 13:32:57
* @FilePath: /newdrawhome/src/CORE/display/base/font.js
*/
import * as THREE from 'three'
const fonturl='./fonts/chn.js'
class Font {
constructor(){
this.font=null;//字体
this.loaded=false;//是否加载完成
}
loadFont(){
let self=this;
let loader=new THREE.FontLoader();
loader.load(fonturl,
function onLoad(fontok){
self.font=fontok;
self.loaded=true;
},
function onProgress(){
},
function onError(e){
console.log("FontLoadFunction"+e);
}
);
}
}
export {Font}
字体类完后在你的应用初始化的时候创建字体类并加载字体。如下:
import {Font} from './display/base/font'
class Application {
constructor() {
this._instance = this;
this._viewerMgr = new ViewerManager();
this._viewerMgr.init();
this._designManager=new DesignManager();
this._designManager.creatDesign('优秀的设计');//创建新设计
this._deleteActionFactory = null;
this._colorSchemeMgr = null;
this._currentPage = window.location.pathname;
this.getActiveView = this.getActiveView.bind(this);
this._font=new Font();//创建字体
this._font.loadFont();//加载字体
}
}
Step4: 绘制中文
主要是利用ThreeJS字体类的generateShapes()方法创建几何体。
.generateShapes( text :String, size :Float) :null
text-- 文本字符串。
size-- (可选)Shapes的缩放,默认值为100。
创建一个Shapes数组,表示使用字体的文本。
主要流程:
let shapes=this.font.font.generateShapes(this.str,100);
let geo=new THREE.ShapeBufferGeometry(shapes);
geo.computeBoundingBox();
let mat=new THREE.MeshBasicMaterial({
color:0x00ff00,
side: THREE.DoubleSide
});
let mesh=new THREE.Mesh(geo,mat);
mesh.position.x = -1 - geo.boundingBox.max.x / 2;
mesh.position.y = 1 - geo.boundingBox.max.y / 2;
mesh.castShadow = false;
this._node.add(mesh);//node为场景节点
其中注意两个地方:
务必调用下.computeBoundingBox(),否则几何体无法生成包围盒。
如果要让文字居中显示请重新计算下mesh的position:
> mesh.position.x = -1 - geo.boundingBox.max.x / 2;
> mesh.position.y = 1 - geo.boundingBox.max.y / 2;
效果图: