threejs绘制中文方案

1. 创建文字几何体

使用threejs自带的helvetiker_bold.typeface字体文件来进行渲染,仅支持渲染英文

export class Text {
  static font: Font;

  data: Mesh;

  static async getFont() {
    if(!this.font) {
      const loader = new FontLoader();
      this.font = await loader.loadAsync('fonts/helvetiker_bold.typeface.json');
    }
    return this.font;
  }

  async setText(text: string) {
    const font = await Text.getFont();
    const geometry = new TextGeometry(text, {
      font: font,
      size: 80,
      height: 5,
      curveSegments: 12,
      bevelEnabled: true,
      bevelThickness: 10,
      bevelSize: 8,
      bevelOffset: 0,
      bevelSegments: 5
    });
    const material = new MeshLambertMaterial({ color: 0x0000ff });
    this.data = new Mesh(geometry, material);
  }
}
渲染英文

自带的 helvetiker_bold 字体并不支持中文,需要找个 ttf 中文字体在 http://gero3.github.io/facetype.js/ 上转换为TypeFace格式,这里以阿里普惠体为例,渲染效果如下

阿里普惠体

但是有两个缺点:

  1. 需要额外加载字体文件,中文字体文件大小高达41.3M,实际使用的话需要对字体文件进行裁剪
  2. 无法渲染emoji表情,都会被渲染为?

2. 使用CSS2DRenderer直接渲染dom

threejs不仅提供了3d渲染器,还提供了把dom元素渲染在3d场景的CSS2DRenderer渲染器

    // CSS2DRenderer
    this.labelRenderer = new CSS2DRenderer();
    this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(this.labelRenderer.domElement);

    // CSS2DObject
    this.scene = new Scene();
    const div = document.createElement("div");
    div.className = "label";
    div.textContent = text;
    this.text= new CSS2DObject(div);
    this.scene.add(this.text);

优点:这样渲染出来的都是真实的dom节点,可以很方便的编写交互逻辑,如果只需要平面的文字,这一方面明显比创建文字几何体更好
缺点:缩放相机时,dom节点没有缩放效果,这个时候可以考虑使用CSS3DRenderer

你可能感兴趣的:(threejs绘制中文方案)