Three.js杂记(十五)—— 汽车展览(下)

2024-04-29 15:12

本文主要是介绍Three.js杂记(十五)—— 汽车展览(下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇文章Three.js杂记(十四)—— 汽车展览·上 - 掘金 (juejin.cn)中主要对切换相机不同位置和鼠标拖拽移动相机焦点做了简单的应用。

那么现在聊聊该如何实现汽车模型自带的三种动画展示了,实际上可以是两种汽车前后盖打开汽车4车门打开,最后一种只是将前两种结合起来了。

关于ThreeJs中动画可以参考:

  • 官方API文档:AnimationAction – three.js docs (threejs.org)
  • ThreeJs中文网:1. 关键帧动画 | Three.js中文网 (webgl3d.cn)

模型动画运行

ThreeJs动画是关键帧动画,在汽车模型导入时,可以从gltf中查找到AnimationClip动画剪辑。

在查找动画这一步上面,我卡了很久,一直没找到动画。原因是我从gltf.sceneanimations上开始查找的,没有找到,甚至还递归遍历内部元素寻找animations。但是最后发现,直接gltf.animations就可以找到三种动画,白白绕了一大圈。

在这里插入图片描述

找到模型动画后,使用AnimationMixer函数生成一个动画混合器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。

接下来将gltf.scene关键帧动画模型的父对象作为参数传入。获得混合器实例mixerclipAction方法获取获取动画剪辑,然后使用play方法播放此动画。可以对循环次数进行限制。

gltfLoader.load中添加以下代码:

// 模型动画
const modelAnimationArr = gltf.animations;
//包含关键帧动画的模型作为参数创建一个播放器
mixer = new THREE.AnimationMixer(gltf.scene);
const clipAction = mixer.clipAction(modelAnimationArr[0]);
clipAction.play(); //播放动画
//不循环播放
clipAction.loop = THREE.LoopOnce; 

当然,现在动画还是不会生效。因为没有执行混合器的update方法,推进混合器时间并更新动画。需要在animate中进行添加,可以使用ThreeJsClock时钟,用于跟踪时间,当然也可以直接使用new Date()

// 如果想播放动画,需要周期性执行`mixer.update()`更新AnimationMixer时间数据
const clock = new THREE.Clock();
function animate() {if (mixer) {//clock.getDelta()方法获得loop()两次执行时间间隔let frameT = clock.getDelta();// 更新播放器相关的时间mixer.update(frameT);}// ...
}

这样一来,汽车第一个动画效果就运行起来了。

在这里插入图片描述


三种动画切换

在成功运行了第一种动画后,接下来就只是一些完善性的工作了。

在原先的面板上添加三种动画的切换按钮吧。

在这里插入图片描述

然后动画的切换比较重要,这里官网API:AnimationAction – three.js docs (threejs.org)

  1. 对于当前所属动画可以设置curIndex,然后如果动画尚未结束,那么先用stop方法结束动画
  2. 判断动画是否结束,可以在混合器上绑定finished监听事件。在动画事件结束之后,重新将curIndex设置为-1
  3. 动画启动时,设置curIndex的值为当前动画的index序号,然后使用play函数进行播放。
  4. 根据我的观察,当前汽车模型的动画最后会把打开的车门又关闭,但是我不希望关闭,可以设置剪辑对象的结束时间,并通过clampWhenFinished让动画停止在最后一帧。
// 切换改变当前汽车动画
let curIndex = -1;
const changeAnimation = (num: number) => {if (curIndex > -1) {// 结束原先动画mixer.clipAction(modelAnimationArr[curIndex]).stop();}curIndex = num;const clipAction = mixer.clipAction(modelAnimationArr[num]);clipAction.time = 2;  // 剪辑对象起始时间clipAction._clip.duration = 10; //剪辑对象设置播放结束时间clipAction.clampWhenFinished = true; // 是否在动画结束时停止播放clipAction.play(); //播放动画//不循环播放clipAction.loop = THREE.LoopOnce; mixer.addEventListener( 'finished', function(e:any) {curIndex = -1;});
}

效果:

在这里插入图片描述

这篇关于Three.js杂记(十五)—— 汽车展览(下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/946435

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

js异步提交form表单的解决方案

1.定义异步提交表单的方法 (通用方法) /*** 异步提交form表单* @param options {form:form表单元素,success:执行成功后处理函数}* <span style="color:#ff0000;"><strong>@注意 后台接收参数要解码否则中文会导致乱码 如:URLDecoder.decode(param,"UTF-8")</strong></span>

js react 笔记 2

起因, 目的: 记录一些 js, react, css 1. 生成一个随机的 uuid // 需要先安装 crypto 模块const { randomUUID } = require('crypto');const uuid = randomUUID();console.log(uuid); // 输出类似 '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

uuid.js 使用

相关代码 import { NIL } from "uuid";/** 验证UUID* 为空 则返回 false* @param uuid* @returns {boolean}*/export function MyUUIDValidate(uuid: any): boolean {if (typeof uuid === "string" && uuid !== NIL) { //uuid