threejs生成字体的3种方法,根据场景自取使用

1,221 阅读1分钟

小白入手threejs,为了实现一个需求尝试了3种方法(网上的数据乱),真心是走了许多弯路,希望分享出来帮助大家!

  • CSS2DRender

这个会出现一个问题就是文字会在其他网格模型之上

function initCityName(cityName, pos) {
  // 实例化css2d的渲染器
  labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(labelRenderer.domElement)
  //设置样式
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.left = '0px';
  labelRenderer.domElement.style.color = 'white'
  labelRenderer.domElement.style.fontSize = '12px'
  // labelRenderer.domElement.style.zIndex = '0';//设置层级
  // 解决添加CSS2DLoader以后轨道控制器不能用的问题
  labelRenderer.domElement.style.pointerEvents = 'none';
  const div = document.createElement('div');
  div.innerHTML = cityName
  const labelObj = new CSS2DObject(div);
  labelObj.name = cityName
  labelObj.position.set(1, 1, 1)
  return labelObj
}
  • Canvas+Sprite精灵图实现

将getCanvas返回值输送到createSprite中,并将返回值添加到scene中。这种方法可以使得相机无论如何旋转文字始终朝向屏幕。

function getCanvas(text, fontStyle = "Bold 25px Times New Roman") {
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext('2d');
  ctx.fillStyle = "#ffffff";
  ctx.font = fontStyle;
  ctx.fillText(text, 0, 120);//写字
  return canvas;
}

function createSprite(canvas, pos) {
  let texture = new THREE.Texture(canvas);
  texture.needsUpdate = true;
  let material = new THREE.SpriteMaterial({
    map: texture
  });
  let mesh = new THREE.Sprite(material);
  mesh.position.set( 0.6, 0.1, 0.2);
  return mesh;
}

  • FontLoader + TextGeometry实现

首先引入FontLoader,和字体helvetikerRegular(英文)或者YaHeiRegular(中文) 中文Microsoft YaHei_Regular.json百度网盘地址:

链接:pan.baidu.com/s/1Dp3qh0fM…

提取码:zfzn

如果需要其他字体,可以自行创建。地址gero3.github.io/facetype.js…,选择任意一个中文字体的ttf文件,然后点击生成即可。

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import helvetikerRegular from 'three/examples/fonts/helvetiker_regular.typeface.json';
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js";

直接根据官网(threejs.org/docs/index.… 的写法会出现问题,所以我使用了一下方法(亲测可用)

TextGeometry()第一个参数需要是字符串,如果需要使用变量,可以使用toString()方法转换一下

  var loader = new FontLoader();
  var font = loader.parse(helvetikerRegular);
  //var font = loader.parse(YaHeiRegular);
  
  const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
    const textGeometry = new TextGeometry(cityName, {
      font: font,
      size: 0.8,  //字体大小
      height: 0.1  //字体高度
    });
    const textMesh = new THREE.Mesh(textGeometry, material);
    textMesh.position.set(1, 1, 1);
    scene.add(textMesh);

以上是所有总结,如果对你有用给宝宝点个赞哦