Threejs进阶之十一:使用FontLoader和TextGeometry创建三维文字

这篇具有很好参考价值的文章主要介绍了Threejs进阶之十一:使用FontLoader和TextGeometry创建三维文字。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Threejs中我们可以通过FontLoader和TextGeometry结合使用来创建三维文字,FontLoader用于加载JSON格式的字体,FontLoader返回值是表示字体的Shape类型的数组;TextGeometry用于将文本生成为单一的几何体。下面我们先来了解下这两个类

FontLoader

用于加载JSON格式的字体的类。返回font, 返回值是表示字体的Shape类型的数组。 其内部使用FileLoader来加载文件。

构造函数

FontLoader( manager : LoadingManager )
manager — 加载器所使用的loadingManager。默认值为THREE.DefaultLoadingManager.

常用方法

FileLoader常用的方法是.load()方法

.load ( url : String, onLoad : Function, onProgress : Function, onError : Function )
url — 文件的URL或者路径
onLoad — 在加载完成时调用。参数是将要被加载的font
onProgress — 在加载过程中调用。参数是包含total和loaded字节的XMLHttpRequest实例。如果server没有设置header的Content-Length,则total值为0
onError — 在加载错误时调用

注意

这里需要注意的是,FontLoader加载的是JSON格式的字体,Threejs默认提供了一些json格式的字体在/examples/fonts中,可以将其拷贝到项目中直接使用。如果里面没有需要的之前,如中文字体,可以通过facetype.js进行字体转换.

TextGeometry 文本缓冲几何体

TextGeometry 用于将文本生成为单一的几何体的类。 它是由一串给定的文本,以及由加载的font和该几何体ExtrudeGeometry父类中的设置所组成的参数来构造的

构造函数

TextGeometry(text : String, parameters : Object)
text — 将要显示的文本。
parameters — 包含有下列参数的对象:

font — THREE.Font的实例。
size — Float类型。字体大小,默认值为100。
height — Float类型。挤出文本的厚度。默认值为50。
curveSegments — Integer类型。(表示文本的)曲线上点的数量。默认值为12。
bevelEnabled — Boolean类型。是否开启斜角,默认为false。
bevelThickness — Float类型。文本上斜角的深度,默认值为20。
bevelSize — Float类型。斜角与原始文本轮廓之间的延伸距离。默认值为8。
bevelSegments — Integer类型。斜角的分段数。默认值为3。

facetype.js在线转换字体

facetype.js在线转换可以将我们想要转换的ttf格式的字体文件转换为json格式的字体文件,其用法非常简单,打开网站,在选择文件中选择需要转换的ttf文件,默认选中Generate a JSON file (.json),不需要修改,点击下面的Convert即可将ttf转换为json格式,并下载到本地
fontloader.js,ThreeJS,javascript,前端,vue.js,html5,3d
这里需要注意,facetype.js只能转换ttf格式的字体

创建三维文字

对FontLoader和TextGeometry有了了解后,我们就可以在场景中创建三维文字了,在我们的vue项目中的components文件夹下新建FontView.vue文件,引入threejs并初始化,这些都是创建Threejs的基本套路,这里就不在赘述了,对Threejs创建的过程还不了解的小伙伴可以看我前面的博客文章。

初始化代码

<template>
  <div id="scene"></div>
</template>
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'  
import { onMounted } from 'vue'
let scene,camera,renderer,controls
onMounted(()=>{
  init()
}) 
function init() {
  initScene()
  initCamera()
  initAxesHelper()
  initLight()
  initRenderer()
  initControls()
  
  animate()
  window.addEventListener('resize',onWindowResize.bind(this))
}
// 初始化场景
function initScene() {
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x808080)
}
// 初始化相机
function initCamera() {
  camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000)
  camera.position.set(0,2,2)  
}
// 辅助轴
function initAxesHelper() {
  const axesHelper = new THREE.AxesHelper(1)
  scene.add(axesHelper)
}
// 灯光
function initLight() {
  const hesLight = new THREE.HemisphereLight(0xffffff,0x444444)
  hesLight.intensity = 0.6
  scene.add(hesLight)

  const dirLight = new THREE.DirectionalLight()
  dirLight.position.set(5,5,5)
  scene.add(dirLight)
}
// 初始化渲染器
function initRenderer() {
  renderer = new THREE.WebGLRenderer({antialias:true}) //抗锯齿
  // 设置屏幕像素比
  renderer.setPixelRatio(window.devicePixelRatio)
  // 设置大小
  renderer.setSize(window.innerWidth,window.innerHeight) 
  // 添加到容器
  document.querySelector('#scene').appendChild(renderer.domElement)
  // 加载阴影
  renderer.shadowMap.enable = true
}
// 初始化轨道控制器
function initControls() {
  controls = new OrbitControls(camera,renderer.domElement)  
  controls.minPolarAngle = 0 //默认0
  // 左键拖动时视窗垂直方向的最大旋转角度。Math.PI/2 为地平线视角
  controls.maxPolarAngle = 80 / 360 * 2 * Math.PI // 默认Math.PI,即可以向下旋转到撒旦视角。 
	controls.update()
}  
function animate() { 
  const delta = clock.getDelta()
 
  renderer.render(scene,camera)
  controls.update(delta) // 当controls.enableDamping=true或者controls.autoRotate=true时调用
  requestAnimationFrame(animate)
 
}
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth,window.innerHeight)
} 
</script>
<style scoped>
</style>

创建三维文字

引用FontLoader和TextGeometry

FontLoader位于three/examples/jsm/loaders/目录下,
TextGeometry位于three/examples/jsm/geometries/目录下

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry' 
创建initFont()方法

创建initFont()方法,在该方法中创建三维文字

创建材质

一个三维文字有两个面组成,分别是文字的正面和拉伸出来的面组成,如果只设置一种材质,则不会有三维立体效果,仍然是二维的文字,可以调整两个材质的颜色不同来观察区别
fontloader.js,ThreeJS,javascript,前端,vue.js,html5,3d

const materials = [
    new THREE.MeshPhongMaterial({
      color:0xffffff,
      flatShading:true
    }),//front
    new THREE.MeshPhongMaterial({color:0xff0000})//back
  ]
实例化FontLoader对象
const loader = new FontLoader()
调用FontLoader的.load方法,在.load方法中设置要调用的字体和加载成功时的回调

在成功的回调中主要处理以下几个逻辑
1、创建TextGeometry,并设置相关参数,
2、创建Mesh,将上面定义的几何体和材质作为参数传入
3、设置Mesh的位置并添加到屏幕

 const font = loader.load(
    // font资源URL 
    'fonts/helvetiker_regular.typeface.json',
    // onLoad回调
    function (font) { 
      const geometry = new TextGeometry('你好 hello',{
        font:font,
        size:0.25, // Float。字体大小,默认值为100。
        height:0.05, //  Float。挤出文本的厚度。默认值为50。
        curveSegments: 12, // Integer (表示文本的)曲线上点的数量。默认值为12。
        bevelEnabled: true, // Boolean 是否开启斜角,默认为false。
        bevelThickness: 0.01, // Float。文本上斜角的深度,默认值为20。
        bevelSize: 0,// Float。斜角与原始文本轮廓之间的延伸距离。默认值为8。
        bevelSegments: 3 // Integer 斜角的分段数。默认值为3。
      })
      const textMesh1 = new THREE.Mesh(geometry,materials)
      textMesh1.position.set(0,0,0)
      scene.add(textMesh1)
    }
  )

在init()函数中调用initFont()方法

在init()函数中调用initFont()方法,刷新浏览器看效果
fontloader.js,ThreeJS,javascript,前端,vue.js,html5,3d

获取文字宽度并向左偏移

我们得到的是从原点开始的一个三维文字,如果我们想要让这个文字的中心与原点重合,即将文字向左偏移一般,应该如何处理呢?
这里我们可以借助Geometry的.computeBoundingBox () 方法,该方法用于计算当前几何体的的边界矩形,该操作会更新已有 .boundingBox。这里注意,边界矩形不会默认计算,我们需要调用该接口指定计算边界矩形,否则保持默认值 null
我们在使用时,首先调用geometry.computeBoundingBox ()方法,然后在geometry.boundingBox属性中获取max和min对应的x、y、z的值,我们根据最大值的x和最小值的x的差值来获取文字边界的长度,从而获取偏移量

geometry.computeBoundingBox()
// console.log(geometry.boundingBox);
const xOffset = (geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2
const textMesh1 = new THREE.Mesh(geometry,materials)
textMesh1.position.set(-xOffset,0,0)
scene.add(textMesh1)

fontloader.js,ThreeJS,javascript,前端,vue.js,html5,3d

添加中文

前面我们提到,要想创建三维的中文文字,需要支持中文的字体的json格式字体文件,我们前面也介绍了如何将ttf文件转换为json格式的字体文件,这里我们将转换好的简体中文直接使用

 const font = loader.load(
    // font资源URL
    'fonts/KaiTi_Regular.json', 
    // onLoad回调
    function (font) {
      console.log(font);
      const geometry = new TextGeometry('欢迎',{
        font:font,
        size:0.25, // Float。字体大小,默认值为100。
        height:0.08, //  Float。挤出文本的厚度。默认值为50。
        curveSegments: 12, // Integer (表示文本的)曲线上点的数量。默认值为12。
        bevelEnabled: true, // Boolean 是否开启斜角,默认为false。
        bevelThickness: 0.01, // Float。文本上斜角的深度,默认值为20。
        bevelSize: 0,// Float。斜角与原始文本轮廓之间的延伸距离。默认值为8。
        bevelSegments: 3 // Integer 斜角的分段数。默认值为3。
      })
      geometry.computeBoundingBox()
      // console.log(geometry.boundingBox);
      const xOffset = (geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2
      const textMesh1 = new THREE.Mesh(geometry,materials)
      textMesh1.position.set(-xOffset,0,0)
      scene.add(textMesh1)
    }
  )

让文字产生倒影效果

要产生倒影效果的三维文字,我们可以在添加一个文字Mesh,将其沿x轴旋转180度,这样就得到了文字的倒影
旋转后得到的文字与原文字在z轴上有偏差,对其进行微调

 geometry.computeBoundingBox()
    
      const xOffset = (geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2
      const textMesh1 = new THREE.Mesh(geometry,materials)
      textMesh1.position.set(-xOffset,0,0)
      scene.add(textMesh1)
      const textMesh2 =new THREE.Mesh(geometry,materials)
      // console.log(geometry.boundingBox);
      textMesh2.position.set(-xOffset,-geometry.boundingBox.min.y-0.03,geometry.boundingBox.max.z-0.01)
      textMesh2.rotation.x = Math.PI
      scene.add(textMesh2)

fontloader.js,ThreeJS,javascript,前端,vue.js,html5,3d
好了,这次就写到这里吧,祝小伙伴们劳动节快乐!喜欢的关注点赞收藏吧文章来源地址https://www.toymoban.com/news/detail-737467.html

到了这里,关于Threejs进阶之十一:使用FontLoader和TextGeometry创建三维文字的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Threejs入门之十四:Threejs中的组(Group)对象

    组其实就是一个集合,将不同的物体添加到一个组中,就形成了一个集合; 比如我们可以创建两个物体,然后将这两个物体使用group.add方法添加到同一个组中 Group的特性 在Threejs的官方文档中介绍Group时说它几乎与Object3D相同,因此,Group的属性和Object3D的相同 .children属性 使用

    2024年02月06日
    浏览(69)
  • quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用)

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇是《quarkus依赖注入》系列的第十一篇,之前的[《拦截器》]学习了拦截器的基础知识,现在咱们要更加深入的了解拦截器,掌握两种高级用法:拦截器属性和重复使用拦截器 先来回顾拦截器的基

    2024年02月13日
    浏览(24)
  • JUC之十一:CompletableFuture用法详解

    前面介绍了 FutureTask ,获取异步执行结果通过get的形式,而且会阻塞主线程,随着开发的越来越越复杂已经无法满足真正开发场景,我们试想一个例子: 我们再炒菜的时候,先洗菜,切菜,炒菜,盛菜,然后吃。。。。。。 如果还用原来的 future 来操作的话,需要每一个步骤

    2024年02月16日
    浏览(28)
  • hive学习笔记之十一:UDTF

    为了验证UDTF的功能,咱们要先把表和数据都准备好: 新建名为t16的表: create table t16( person_name string, string_field string ) row format delimited fields terminated by ‘|’ stored as textfile; 本地新建文本文件016.txt,内容如下: tom|1:province:guangdong jerry|2:city:shenzhen john|3 导入数据: load data loca

    2024年04月08日
    浏览(25)
  • 软件设计模式系列之十一——装饰模式

    当谈到设计软件系统时,经常需要考虑如何使系统更加灵活、可扩展和易维护。设计模式是一种被广泛采用的方法,用于解决常见的设计问题,并提供了一套可重用的解决方案。装饰模式(Decorator Pattern)是一种结构型设计模式,它允许您在不改变对象接口的情况下动态地添

    2024年02月08日
    浏览(30)
  • ThreeJS-纹理旋转、重复(十一)

     文档:three.js docs 关键代码:    //设置旋转中心,默认左下角     docColorLoader.center.set(0.5,0.5);     //围绕旋转中心逆时针旋转45度     docColorLoader.rotation = Math.PI/4; 完整代码: template   div id=\\\"three_div\\\"/div /template   script import * as THREE from \\\"three\\\"; import { OrbitControls } from \\\"three/example

    2023年04月08日
    浏览(31)
  • Verilog基础之十一、移位寄存器实现

    目录 一、前言 二、工程设计 ​2.1 工程代码 2.2 综合结果 2.3 仿真结果     移位寄存器SRL在工程中属于使用频率较高个模块,可用于存储数据,实现串并转换;根据数据移动方向可分为左移寄存器,右移寄存器,左移是向数据高位移动,右移是向数据低位移动。  工程中包

    2024年02月11日
    浏览(32)
  • K8S初级入门系列之十一-安全

        安全是K8S重要的特性,在K8S初级入门系列之四-Namespace/ConfigMap/Secret章节,我们已经已经了解了Namespace,Secret与安全相关的知识。本篇将梳理K8S在安全方面的策略。主要包括两个方面,API安全访问策略以及Pod安全策略。 在介绍安全前,我们先了解下用户和用户组的概念。

    2024年02月16日
    浏览(39)
  • 软件开发项目文档系列之十一如何撰写系统部署方案

    撰写系统部署文档在于为项目提供了关键的操作手册,它不仅标准化了部署流程、传递了关键知识,还降低了系统故障排查和修复的难度,减少了沟通复杂性,确保了合规性和可维护性,为项目的成功实施和稳定运行提供了坚实的基础。系统部署文档充当了项目成功的关键工

    2024年02月05日
    浏览(36)
  • Net 高级调试之十一:托管堆布局架构和对象分配机制

    一、简介 今天是《Net 高级调试》的第十一篇文章,这篇文章来的有点晚,因为,最近比较忙,就没时间写文章了。现在终于有点时间,继续开始我们这个系列。这篇文章我们主要介绍托管堆的架构,对象的分配机制,我们如何查找在托管堆上的对象,我学完这章,很多以前

    2024年02月05日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包