three.js显示中文字体与tween应用详析


Posted in Javascript onJanuary 04, 2021

今天郭先生说一下如何在three中显示中文字体,然后结合tween实现文字位置的动画。线案例请点击chinese-font,

1. 生成中文字体

我们都使用过three.js的FontLoader加载typeface.json实现font的使用,但是很多案例都是英文字体,那么如何来生成中文字体呢?现在我们可以通过Facetype.js实现ttf向typeface.json的转换。 首先我们在网上下载ttf中文字体(或者在电脑的C:\Windows\Fonts直接复制一份中文的ttf字体),然后我们登陆Facetype.js网站,选中准备好的ttf文件,点击convert即可。得到的json文件就可以使用FontLoader加载了,其实还是挺简单的,中文ttf一般都比较大,所以在选择喜欢字体的同时,也要考虑好文件的大小。

2. tween操作文字动画

之前也说过tween动画,不过我觉得挺有意思的,我们就拿百家姓来作文字素材。

three.js显示中文字体与tween应用详析

three.js显示中文字体与tween应用详析

three.js显示中文字体与tween应用详析

效果就是这样的,我们让tween实现从图一到图二到图三再到图一的动画,每个汉字除了位置的变化还有朝向(lookAt)的变化。这里的lookAt方法就是设置物体的朝向。好了开始上代码。

1.设置点的位置和朝向

图一中点的位置可以在平面几何体中取点

let vertices1 = new THREE.PlaneGeometry(1400, 900, 13, 6).vertices;

他们的朝向相对于每个字来说都是Vector3(0, 0, 1),所以可以设置为

d.position.clone().add(Vector3(0, 0, 1)) //这里的d.position就是每个点的位置

图二中点的位置可以在球体中获取

let vertices2 = new THREE.SphereGeometry(500, 12, 9).vertices;

他们的朝向很容易找,就是朝向中心点就可以Vector3(0, 0, 0) 图三中的点可以通过计算得到,就是一组旋转上升的点

for(let i=0; i<98; i++) {
 let x = Math.sin(Math.PI / 12 * i) * 400;
 let y = (49 - i) * 8;
 let z = Math.cos(Math.PI / 12 * i) * 400;
 positions3.push(new THREE.Vector3(x,y,z));
}

他们的朝向可以设置为

new THREE.Vector3(0, d.position.y, 0) //d.position.y就是点的y坐标

这样就设置好了点,接下来就制作动画

2.tween动画

首先初始化三个动画

initTween() {
 var pos = { time: 0 };
 tween1 = new TWEEN.Tween(pos).to({ time: 1 }, 1000);
 tween2 = new TWEEN.Tween(pos).to({ time: 2 }, 1000);
 tween3 = new TWEEN.Tween(pos).to({ time: 0 }, 1000);
 tween1.easing(TWEEN.Easing.Linear.None);
 tween2.easing(TWEEN.Easing.Linear.None);
 tween3.easing(TWEEN.Easing.Linear.None);
 tween1.onUpdate(onUpdate);
 tween2.onUpdate(onUpdate);
 tween3.onUpdate(onUpdate);
}

这里的easing是动画的缓动效果里面有很多种,不妨打印出来看一下

three.js显示中文字体与tween应用详析

然后就是onUpdate方法

function onUpdate() {
 let time = this._object.time; //动画时刻值
 if(flag == 0) {//这里有三段动画flag判断是那一段动画
 group.children.forEach((d, i) => {//group里面包含着所有文字网格
  d.position.copy(positions3[i].clone().multiplyScalar(time / 2).add(positions1[i].clone().multiplyScalar(1 - time / 2)));
  d.lookAt((new THREE.Vector3(0, d.position.y, 0).multiplyScalar(time / 2)).add(d.position.clone().add(lookAt1).multiplyScalar(1 - time / 2)));
 })
 } else if(flag == 1) {
 group.children.forEach((d, i) => {
  d.position.copy(positions1[i].clone().multiplyScalar(1 - time).add(positions2[i].clone().multiplyScalar(time)));
  d.lookAt((d.position.clone().add(lookAt1).multiplyScalar(1 - time)).add(lookAt2.multiplyScalar(time)));
 })
 } else if(flag == 2) {
 group.children.forEach((d, i) => {
  d.position.copy(positions2[i].clone().multiplyScalar(2 - time).add(positions3[i].clone().multiplyScalar(time - 1)));
  d.lookAt((lookAt2.multiplyScalar(2 - time)).add(new THREE.Vector3(0, d.position.y, 0).multiplyScalar(time - 1)));
 })
 }
}

最后通过点击触发

click() {
 tween1.stop();
 tween2.stop();
 tween3.stop();
 if(flag == 0) {
 tween1.start();
 } else if(flag == 1) {
 tween2.start();
 } else if(flag == 2) {
 tween3.start();
 }
 flag = (flag + 1) % 3;
},

这里注意,由于点击切换的时候动画上一个动画可能没有完成,所以先调用stop方法,让动画先停下来。别忘了在render函数中调用TWEEN.update(),不然动画是不会执行的。

总结

到此这篇关于three.js显示中文字体与tween应用的文章就介绍到这了,更多相关three.js显示中文字体与tween应用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

版权声明:本文为郭志强的原创文章,原文链接:https://www.mrguo.link

Javascript 相关文章推荐
$.ajax json数据传递方法
Nov 19 Javascript
js+CSS 图片等比缩小并垂直居中实现代码
Dec 01 Javascript
JavaScript 异步方法队列链实现代码分析
Jun 05 Javascript
JS求平均值的小例子
Nov 29 Javascript
javascript中Date对象的getDay方法使用指南
Dec 22 Javascript
JS从一组数据中找到指定的单条数据的方法
Jun 02 Javascript
整理关于Bootstrap排版的慕课笔记
Mar 29 Javascript
聊聊JavaScript如何实现继承及特点
Apr 07 Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
Jun 26 Javascript
JS根据Unix时间戳显示发布时间是多久前【项目实测】
Jul 10 Javascript
小程序实现日历左右滑动效果
Oct 21 Javascript
JavaScript简单编程实例学习
Feb 14 Javascript
js用正则表达式筛选年月日的实例方法
Jan 04 #Javascript
vue中父子组件的参数传递和应用示例
Jan 04 #Vue.js
如何在VUE中使用vue-awesome-swiper
Jan 04 #Vue.js
vue项目如何监听localStorage或sessionStorage的变化
Jan 04 #Vue.js
element-ui封装一个Table模板组件的示例
Jan 04 #Javascript
ES2020让代码更优美的运算符 (?.) (??)
Jan 04 #Javascript
详解阿里Node.js技术文档之process模块学习指南
Jan 04 #Javascript
You might like
Android AsyncTack 异步任务实例详解
2016/11/02 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
对laravel in 查询的使用方法详解
2019/10/09 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
js报错 Object doesn't support this property or method的原因分析
2011/03/31 Javascript
js history对象简单实现返回和前进
2013/10/30 Javascript
浅析JavaScript中的delete运算符
2013/11/30 Javascript
jQuery中的val()示例应用
2014/02/26 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
Javascript简单实现面向对象编程继承实例代码
2015/11/27 Javascript
js获取隐藏元素宽高的实现方法
2016/05/19 Javascript
javascript鼠标滑过显示二级菜单特效
2020/11/18 Javascript
ros::spin() 和 ros::spinOnce()函数的区别及详解
2016/10/01 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
Express与NodeJs创建服务器的两种方法
2017/02/06 NodeJs
详解从angular-cli:1.0.0-beta.28.3升级到@angular/cli:1.0.0
2017/05/22 Javascript
nodejs实现OAuth2.0授权服务认证
2017/12/27 NodeJs
可能被忽略的一些JavaScript数组方法细节
2019/02/28 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
vue 兄弟组件的信息传递的方法实例详解
2019/08/30 Javascript
详解JavaScript 作用域
2020/07/14 Javascript
python模拟登录百度代码分享(获取百度贴吧等级)
2013/12/27 Python
python pandas写入excel文件的方法示例
2019/06/25 Python
pandas分区间,算频率的实例
2019/07/04 Python
Python绘制动态水球图过程详解
2020/06/03 Python
python实现AHP算法的方法实例(层次分析法)
2020/09/09 Python
欧迪办公美国官网:Office Depot
2016/08/22 全球购物
伦敦最有品味的百货:Liberty London
2016/11/12 全球购物
美国钻石商店:Zales
2016/11/20 全球购物
一套带答案的C++笔试题
2014/01/10 面试题
遇到的Mysql的面试题
2014/06/29 面试题
中学生运动会入场词
2014/02/12 职场文书
毕业班工作总结
2015/08/10 职场文书
煤矿安全生产管理协议书
2016/03/22 职场文书
500字作文之难忘的同学
2019/12/20 职场文书
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js