import * as THREE from 'three'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let scene, camera, renderer; let bone_root, bone_skl_root, bone_body, bone_mouth, bone_mouth_1, bone_leaf_l, bone_leaf_r; let clock = new THREE.Clock(); function init() { // 创建场景、相机和渲染器 scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 1000); renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.setClearColor(0x000000, 0); // 第二个参数0表示完全透明 renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加光照 const pointLight1 = new THREE.PointLight(0xffffff, 10, 100); pointLight1.position.set(1, 2, 2); scene.add(pointLight1); const pointLight2 = new THREE.PointLight(0xffffff, 10, 100); pointLight2.position.set(-1, 2, 2); scene.add(pointLight2); const ambientLight = new THREE.AmbientLight(0xffffff, 1.0); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0); scene.add(directionalLight); // 加载模型 const loader = new GLTFLoader(); loader.load('TalkingFlower.gltf', function (gltf) { scene.add(gltf.scene); gltf.scene.traverse(function (object) { if (object.isBone) { console.log(object); // 打印出骨骼信息,帮助你找到需要的骨骼 if (object.name === 'Root') bone_root = object; if (object.name === 'Skl_Root') bone_skl_root = object; if (object.name === 'Body') bone_body = object; if (object.name === 'Mouth') bone_mouth = object; if (object.name === 'Mouth_1') bone_mouth_1 = object; if (object.name === 'Leaf_L') bone_leaf_l = object; if (object.name === 'Leaf_R') bone_leaf_r = object; } }); bone_leaf_r.position.z = -0.1; bone_leaf_l.position.z = -0.1; bone_leaf_r.position.x = -0.02; bone_leaf_l.position.x = 0.02; bone_mouth.position.y -= 0.05; bone_mouth.rotation.z -= 0.1; }, undefined, function (error) { console.error(error); }); camera.position.z = 2; camera.position.y = 0.25; } // 设置动画相关变量 let frameCount = 0; const totalFrames = 120; // 一个循环的总帧数 function animate() { requestAnimationFrame(animate); // 更新帧计数器 frameCount++; // 每120帧重置帧计数器 if (frameCount > totalFrames) { frameCount = 0; } // 获取经过的时间(秒) let elapsed = clock.getElapsedTime(); // 设置动画周期(120 帧约等于 2 秒) let cycleDuration = 2; // 计算当前周期的相对时间 let cycleTime = elapsed % cycleDuration; // 使用正弦函数计算位置和角度 let theta = (cycleTime / cycleDuration) * Math.PI * 2; let mouth_position = Math.sin(theta) * 0.02; let mouth_angle = Math.cos(theta) * 0.1; let leaf_angle = Math.sin(theta * 4) * 0.05; // 应用变化到骨骼 bone_mouth_1.scale.set(1, 0.8, 0.75); bone_mouth.position.x = mouth_position; bone_mouth.rotation.z = mouth_angle; bone_leaf_r.rotation.z = 9/8*Math.PI + leaf_angle; bone_leaf_l.rotation.z = 1/8*Math.PI + leaf_angle; renderer.render(scene, camera); } init(); animate();