<div style="margin: 8px auto; position: absolute; color: #eee;">
<button id="btnPlay" value="btn">暂停/继续动画</button><span> (提示:动画可手动翻转)</span>
</div>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.ihwx.cn/three@0.176.0/build/three.module.js",
"three/addons/": "https://unpkg.ihwx.cn/three@0.176.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three"; // 主模块
import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // 相机轨道控制器
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; // GLTF模型加载器
const scene = new THREE.Scene(); // 场景
const clock = new THREE.Clock(); // 时钟
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); // 相机
camera.position.set(5, 0, 10); // 相机位置
const renderer = new THREE.WebGLRenderer({ antialias: true }); // 渲染器
renderer.setSize(window.innerWidth, window.innerHeight); // 渲染范围
//renderer.outputEncoding = THREE.sRGBEncoding; // 保真(可选)
const controls = new OrbitControls(camera, renderer.domElement); // 加载相机轨道控制器
document.body.appendChild(renderer.domElement); // 渲染器元素加载到文档
scene.add(new THREE.AmbientLight(0xcccccc), new THREE.PointLight(0xffffff, 100)); // 场景加载环境光和点光源
let mixer; // 动画混合气变量
// 加载 .gbl 模型
new GLTFLoader().load('https://638183.freep.cn/638183/web/3models/Parrot.glb', function (gltf) {
const model = gltf.scene; // 模型节点
const scale = 0.05; // 模型缩放系数
model.scale.set(scale, scale, scale); // 模型缩放
scene.add(model); // 模型节点加入到场景
mixer = new THREE.AnimationMixer(model); // 动画混合气变量赋值
// 若模型有动画则运行之
if (gltf.animations.length > 0) {
const clip = mixer.clipAction(gltf.animations[0]);
clip.play();
}
animate(); // 运行动画函数
});
// 窗口自适应
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// 动画函数
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // 动画频率
mixer.update(delta); // 更新动画数据
renderer.render(scene, camera);
}
btnPlay.onclick = () => clock.running ? clock.stop() : clock.start(); // 动画交互
</script>