three.js : 独立控制图形对象
以下代码,使用 cubes 数组变量保存立方体对象,每一个对象记为 { id: id, name: 'name', step: step },其中,id 指向所创建的立方体,name 指向立方体的名称,step 指向立方体运动歩幅。然后通过 three.js 射线类判断被点击的图形对象,若和 cubes 存储的 name 相一致,则驱动该图形对象的运动歩幅,从而达到每一个图形对象均可独立控制的目的。
<script type="module"> import * as THREE from 'https://esm.sh/three'; // 导入three.js模块 // 初始化场景、相机、渲染器 const scene = new THREE.Scene; const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 5); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); let cubes = [], intersects = []; // 立方体合集、几何体合集 // 正方体几何体 const geometry = new THREE.BoxGeometry(1, 1, 1); geometry.rotateX(Math.PI / 3); geometry.rotateY(Math.PI / 2); // 创建两种标准材质 : 一种各面随机色,另一种金色 const material1 = Array.from({length: 6}, () => new THREE.MeshStandardMaterial({ color: 0xffffff * Math.random() })); const material2 = new THREE.MeshStandardMaterial({ color: 0xffd700 }); const cube1 = new THREE.Mesh(geometry, material1); const cube2 = new THREE.Mesh(geometry, material2); cube1.position.y += 1; cube2.position.y += -1; cube1.name = 'cube1'; cube2.name = 'cube2'; cubes.push({ id: cube1, name: 'cube1', step: 0.01 }, { id: cube2, name: 'cube2', step: 0.01 }); scene.add(cube1, cube2); // 环境光 const AmbientLight = new THREE.AmbientLight('yellow') scene.add(AmbientLight) // 自然光 const hemiLight = new THREE.HemisphereLight(0xffffff, 0x000000, 1) hemiLight.position.set(0, 100, 0) scene.add(hemiLight) // 以下借助three射线类判断图形和设备指针的位置关系 let raycaster = new THREE.Raycaster(); // 实例化射线拾取模型 const pointer = new THREE.Vector2(); // 实例化二维向量点结构 // 判断函数 :检测指针是否在three绘制的图形上 const isMess = (event) => { pointer.x = (event.clientX / window.innerWidth) * 2 - 1; pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(pointer, camera); intersects = raycaster.intersectObjects([cube1, cube2], true); // 参数true表示为不拾取图形对象的子对象 return intersects.length > 0; } // 动画 :根据 step 变量值驱动对象运动或不运动 const animate = () => { cubes.forEach(cube => cube.id.rotation.y += cube.step); renderer.render(scene, camera); requestAnimationFrame(animate); }; // 页面单击事件 :点击到立方体对象控制其 step 变量的值 document.onclick = (e) => { if (!isMess(e)) return; const name = intersects[0].object.name; // 被点击的几何体名称 cubes.forEach(cube => { // 立方体名称若等于几何体名称 if (cube.name === name) { cube.step = cube.step === 0 ? 0.01 : 0; } }); }; // 鼠标指针移入立方体对象时显示手形图标 document.onmousemove = (e) => { document.body.style.cursor = isMess(e) ? 'pointer' : 'default'; }; window.onresize = () => renderer.setSize(window.innerWidth, window.innerHeight); // 适应窗口变化 animate(); // 执行动画函数 </script> <!-- 预览页面CSS --> <style> body { margin: 0; background: linear-gradient(#eee, #333); } </style>
前一篇: three.js几何体之圆锥缓冲几何体
下一篇: three.js几何体之圆柱缓冲几何体
发表评论:
评论列表 [1条]
#1 | 飞飞 于 2025-5-14 19:50 发布: 两个立方体可以独立控制运动。。。