马黑PHP整站系统

ThreeJS:罗列并运行GLTF模型所有动画

位置: 首页 > 代码集锦[ 发布时间: 2025.7.4  作者: 马黑  阅读: 45 ]
<div id="msgDiv" style="margin:8px auto;padding:6px;position:absolute;z-index:3;">
	<span>运动模式:</span>
</div>

<script type="importmap">
	{
		"imports": {
			"three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
			"three/addons/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
		}
	}
</script>

<script type="module">
    import { THREE, scene, camera, renderer, clock, basic3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
    import { OrbitControls } from "three/addons/controls/OrbitControls.js";
    import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

	basic3(); // 启动ThreeJS运行环境

	renderer.outputEncoding = THREE.sRGBEncoding; // 渲染器启用sRGB编码

	const controls = new OrbitControls(camera, renderer.domElement); // 启用轨道控制器

	let mixer, actions = [], btns = []; // 混合器、动画数组、按钮
	const url = 'https://638183.freep.cn/638183/web/3models/RobotExpressive.glb'; // 模型路径

	scene.add(new THREE.AmbientLight()); // 环境光

	// 加载模型 :gltf为模型对象
	new GLTFLoader().load(url, gltf => {
		const model = gltf.scene; // 模型场景
		const scale = 0.5; // 缩放系数
		model.scale.set(scale, scale, scale); // 缩放
		//model.rotateY(Math.PI / 5); // 旋转
		model.position.y -= 1; // 下移
		scene.add(model); // 添加模型场景到ThreeJS场景
		mixer = new THREE.AnimationMixer(model); // 混合器赋值
		// 若模型集成有动画 :添加到数组、创建交互按钮
		if (gltf.animations.length > 0) {
			gltf.animations.forEach( (a, k) => {
				actions.push(a); // 加到数组
				//创建按钮
				const btn = document.createElement('button');
				btn.style.cssText += 'margin: 4px; padding: 6px;';
				btn.value = k;
				btn.textContent = a.name;
				btn.onclick = () => playModel(k); // 播放指定动画
				btns.push(btn);
				msgDiv.appendChild(btn);
			});
			playModel(); // 随机播放动画
		}
		animate();
 	});

	// 循环播放ThreeJS动画
	function animate() {
		requestAnimationFrame(animate);
		camera.lookAt(0, 0, 0); // 相机总是对准场景中央
		const delta = clock.getDelta();
		mixer.update(delta);
		renderer.render(scene, camera);
	}

	// 播放模型动画 :不指定索引则随机播放
	function playModel(idx = null) {
		const playIdx = idx !== null ? idx : Math.floor(Math.random() * actions.length);
		for (let k = 0; k < actions.length; k ++) {
			const clip = mixer.clipAction(actions[k]);
			k === playIdx ? (clip.play(), btns[k].disabled = true) : (clip.stop(), btns[k].disabled = false);
		}
	}
</script>

前一篇: Tween动画链接补间及其播放停止暂停继续
下一篇: 漂亮的HTML立方体

发表评论:

       

评论列表 [1条]

#1 | 悄然 于 2025-7-4 13:45 发布: 我的天哪,这个机器人有这么多不同的状态。。贴子里是把这些动作合并在一起了对吧

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com