three.js官方案例(animation / keyframes)webgl_animation_keyframes.html学习




// 引入相关库
import * as THREE from 'three';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
 
// 场景、摄像机、渲染器等初始化代码略...
 
// 加载模型
const loader = new GLTFLoader();
loader.load( 'models/animals/horse.gltf', function ( gltf ) {
 
    // 获取模型中的角色
    const horse = gltf.scene.children[ 0 ];
    horse.scale.set( 0.01, 0.01, 0.01 ); // 缩小模型
    scene.add( horse );
 
    // 设置动画和关键帧
    const mixer = new THREE.AnimationMixer( horse );
    const action = mixer.clipAction( gltf.animations[ 0 ] );
 
    // 播放动画
    action.play();
 
    // 更新动画
    mixer.timeScale = 0.8; // 放慢动画
 
    // 创建关键帧
    const keyframes = [];
    keyframes.push({ time: 0, position: horse.position.clone() }); // 记录当前位置
 
    // 设置动画更新时的回调函数
    const clock = new THREE.Clock();
    const update = function ( deltaTime ) {
        const time = clock.getElapsedTime();
 
        // 每隔一定时间记录关键帧
        if ( time > keyframes[ keyframes.length - 1 ].time + 2 ) {
            keyframes.push({
                time: time,
                position: horse.position.clone()
            });
        }
 
        // 插值计算关键帧之间的位置
        const keys = keyframes.length;
        if ( keys > 1 ) {
            const prevKey = keyframes[ keys - 2 ];
            const nextKey = keyframes[ keys - 1 ];
            const p = ( time - prevKey.time ) / ( nextKey.time - prevKey.time );
            horse.position.lerpVectors( prevKey.position, nextKey.position, p );
        }
 
        // 更新动画
        mixer.update( deltaTime );
 
        // 渲染场景
        renderer.render( scene, camera );
    };
 
    // 监听浏览器窗口大小变化
    window.addEventListener( 'resize', onWindowResize );
 
    // 渲染循环
    function animate() {
        requestAnimationFrame( animate );
        update();
    }
 
    animate();
 
}, undefined, function ( error ) {
    console.error( error );
} );
 
// 其他函数和监听器略...

这段代码示例展示了如何在Three.js中加载一个glTF模型,并设置其动画和关键帧记录。它演示了如何使用THREE.AnimationMixer来播放和控制模型的动画,并使用关键帧数组来记录和插值计算模型的位置。最后,它提供了一个update函数,该函数在每一帧调用,用于更新动画状态和渲染场景。

评论已关闭

推荐阅读

Vue中使用mind-map实现在线思维导图
2024年08月04日
VUE
Web前端最全Vue实现免密登录跳转的方式_vue怎么样不登录返回首页,最强技术实现
2024年08月04日
VUE
vue3 项目搭建教程(基于create-vue,vite,Vite + Vue)
2024年08月04日
VUE
Vue-颜色选择器实现方案——>Vue-Color( 实战*1+ Demo*7)
2024年08月04日
VUE
Vue项目卡顿慢加载?这些优化技巧告诉你!_vue数据多渲染卡顿
2024年08月04日
VUE
vue中的keep-alive详解与应用场景
2024年08月04日
VUE
Vue、React实现excel导出功能(三种实现方式保姆级讲解)
2024年08月04日
vue-office/docx插件实现docx文件预览
2024年08月04日
VUE
java调用js文件的两种方法(支持V8引擎)
2024年08月04日
JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
2024年08月04日
两周从爬虫小白变大神 _yjs_js_security_passport
2024年08月04日
JS笔记(对象、函数、数组)
2024年08月04日
Markdown.js:强大的纯JavaScript Markdown解析器
2024年08月04日
Vue项目:js模拟点击a标签下载文件并重命名,URL文件地址下载方法、请求接口下载文件方法总结。
2024年08月04日
vue 父组件怎么获取子组件里面的data数据
2024年08月04日
VUE
个人开发实现AI套壳网站快速搭建(Vue+elementUI+SpringBoot)
2024年08月04日
el-table 表格封装并改造实现单元格可编辑
2024年08月04日
none
nodejs环境下创建vue项目、SSH密钥登陆!!!
2024年08月04日
vue+quill+element-ui实现视频、图片上传及缩放保姆级教程,轻松使用富文本
2024年08月04日
【three.js】22. Imported Models导入模型
2024年08月04日