广州seo排名外包,温州seo教程,成都门户网站建设公司,tv网站建设内容摘要#xff1a;使用Three.js库构建了一个交互式的3D场景。组件中创建了一个机器人模型#xff0c;包括头部、眼睛、触角、身体和四肢#xff0c;以及两个相同的机器人实例以实现动态效果。场景中还加入了粒子效果#xff0c;模拟星系环境#xff0c;增强了视觉效果。… 内容摘要使用Three.js库构建了一个交互式的3D场景。组件中创建了一个机器人模型包括头部、眼睛、触角、身体和四肢以及两个相同的机器人实例以实现动态效果。场景中还加入了粒子效果模拟星系环境增强了视觉效果。通过OrbitControls用户可以对机器人进行旋转控制。组件在渲染时会根据用户界面的变化动态调整渲染并在指定的div容器中显示。整体上这个组件提供了一个基础的3D动画展示和用户交互的框架。 在React中集成Three.js库创建一个动态渲染的3D场景。定义和渲染多个Three.js几何体如机器人身体、胳膊、腿、眼睛和触角。添加交互性如旋转和轨道控制器以提供更好的用户体验。创建粒子特效模拟星系环境与机器人形成对比。 一、项目搭建reactthree.js 实现这样的效果需要安装three.js包至于使用vue还是react框架都行因为three.js只需要一个div作为挂载点即可。也用不到框架的细节。本文以react为例实现。 依次执行以下命令完成react项目的初始化和threejs的安装 良好的编码习惯要求我们在views里新增一个robot文件夹根据react组件的特效用.tsx后缀表示是组件。定义一个方法名为Robot的function并将其默认导出。react的特点函数式组件。方法名就是组件名这个是react内部进行编译处理的。跟vue差别很大。 在App.tsx中引入robot组件 npm run start 运行即可看到效果 二、实现细节 实现机器人及星空特效其中机器人构建可以是批量的机器人身体又可以拆分为脑袋、触角、眼睛、身体、胳膊、腿等细节。每个部分单独用有方法实现逻辑拆分清晰。 对单个3D模型来说需要三个东西meshgeometry(几何)material(材料) 几何体Geometry: THREE.SphereGeometry: 用于创建球形几何体。它接受几个参数包括半径radius、宽度分段widthSegments、高度分段heightSegments、水平起始角度phiStart、水平扫描角度phiLength、垂直起始角度thetaStart和垂直扫描角度thetaLength。THREE.CapsuleGeometry: 用于创建胶囊形状的几何体可以看作是一个圆柱体两端加上半球体。它接受两个参数分别是半径radius和高度height。THREE.CylinderGeometry :创建圆柱体。圆柱体由两个圆形底面和一个侧面组成。这个类的作用是定义一个圆柱形状的3D几何体它可以在 Three.js 的场景中被渲染。 材质Material: THREE.MeshStandardMaterial: 用于创建标准网格材质它提供了多种物理渲染特性如颜色color、粗糙度roughness和金属度metalness等。 网格Mesh: THREE.Mesh: 网格是几何体和材质的组合可以通过它将几何体渲染到场景中。它接受一个几何体geometry和一个材质material作为参数。 这里方便解耦单个方法只生成模型在调用方法的地方确定模型的位置。 机器人脑袋
//机器人脑袋
function createHead() {//SphereGeometry创建球形几何体const head new THREE.SphereGeometry(4, 32, 16, 0, Math.PI * 2, 0, Math.PI * 0.5);const headMaterial new THREE.MeshStandardMaterial({color: 0x43b988,roughness: 0.5,metalness: 1.0,});const headMesh new THREE.Mesh(head, headMaterial);return headMesh;
}
机器人触角
//触角
function generateHorn(y: number, z: number, angle: number) {//触角 CapsuleGeometry 创建胶囊形状的几何体。胶囊形状可以看作是一个圆柱体两端加上半球体const line new THREE.CapsuleGeometry(0.1, 2);const lineMaterial new THREE.MeshStandardMaterial({color: 0x43b988,roughness: 0.5,metalness: 1.0,});const lineMesh new THREE.Mesh(line, lineMaterial);lineMesh.position.y y;lineMesh.position.z z;lineMesh.rotation.x angle;return lineMesh;
}
机器人眼睛
//机器人眼睛
function generateEye(x: number, y: number, z: number) {//SphereGeometry创建球形几何体const eye new THREE.SphereGeometry(0.5, 32, 16, 0, Math.PI * 2, 0, Math.PI * 2);const eyeMaterial new THREE.MeshStandardMaterial({color: 0x212121,roughness: 0.5,metalness: 1.0,});const eyeMesh new THREE.Mesh(eye, eyeMaterial);eyeMesh.position.x x;eyeMesh.position.y y;eyeMesh.position.z z;return eyeMesh;
}
机器人身体
//机器人身体
function generateBody() {//CylinderGeometry第一个参数是上部分圆的半径第二个参数是下部分圆的半径第三个参数是高度材质使用的跟腿一样const body new THREE.CylinderGeometry(4, 4, 6);const bodyMaterial new THREE.MeshStandardMaterial({color: 0x43b988,roughness: 0.5,metalness: 1.0,});const bodyMesh new THREE.Mesh(body, bodyMaterial);return bodyMesh;
}
机器人胳膊
//胳膊、腿
function generateLegs(y: number, z: number) {const leg1 new THREE.CapsuleGeometry(1, 4);const legMaterial1 new THREE.MeshStandardMaterial({color: 0x43b988,roughness: 0.5,metalness: 1.0,});const leg1Mesh new THREE.Mesh(leg1, legMaterial1);leg1Mesh.position.y y;leg1Mesh.position.z z;return leg1Mesh;
}
创建机器人
//创建机器人
function generateRobot() {// 创建一个Three.js对象用于存放机器人const robot new THREE.Object3D();const headMesh createHead();headMesh.position.y 6.5;robot.add(headMesh);//眼睛const leftEye generateEye(3, 8, -2);const rightEye generateEye(3, 8, 2);robot.add(leftEye);robot.add(rightEye);const leftHorn generateHorn(11, -1, (-Math.PI * 30) / 180);const rightHorn generateHorn(11, 1, (Math.PI * 30) / 180);robot.add(leftHorn);robot.add(rightHorn);const body generateBody();body.position.y 4;robot.add(body);// 生成机器人左腿robot.add(generateLegs(0, -2));// 生成机器人右腿robot.add(generateLegs(0, 2));//胳膊robot.add(generateLegs(3, 5));robot.add(generateLegs(3, -5));//物体缩放robot.scale.x 0.3;robot.scale.y 0.3;robot.scale.z 0.3;return robot;
}
生成粒子场景
//创建粒子星星
function generateStarts(num: number) {//制作粒子特效const starts new THREE.Object3D();const obj new THREE.SphereGeometry(0.2, 3, 3);const material new THREE.MeshStandardMaterial({color: 0x43b988,roughness: 0.5,metalness: 5,});const mesh new THREE.Mesh(obj, material);for (let i 0; i num; i) {const target new THREE.Mesh();target.copy(mesh);target.position.x Math.floor(Math.random() * 18 Math.floor(Math.random() * -18));target.position.y Math.floor(Math.random() * 18 Math.floor(Math.random() * -18));target.position.z Math.floor(Math.random() * 18 Math.floor(Math.random() * -18));starts.add(target);}return starts;
} 主方法
Scene场景 scene是一个THREE.Scene对象它是Three.js中场景的容器用于组织和管理3D对象如几何体、材质、相机和灯光等。 add(object): 这个方法用于将对象例如机器人、光源、粒子等添加到场景中。
示例代码中使用了多次
scene.add(robot);
scene.add(robot2);
scene.add(straightLight);
scene.add(starts);
PerspectiveCamera透视相机 3D场景中的相机视角。一般都是使用透视相机PerspectiveCamera第一个参数是fov表示相机所成的一个四棱台远面与近面之间的夹角夹角越小看见的东西越少夹角越大看见的东西就越多但是周围会显的比较模糊一般取值以4575最佳第二个参数aspect是近裁面的一个宽高比我们用窗口的宽除以窗口的高就可以了第三个值near与第四个值far分别是与近面和远面的距离这里设置的值分别为0.1与1000调用camera.positon.set表示设置相机的位置默认都是在(0,0,0)的位置我们这里给相机设置的位置为(15,12,8),并且让相机正对(0,0,0)的位置 PerspectiveCamera是Three.js中的透视投影相机文中使用的参数解释如下 75视角Field of ViewFOV决定了视场的宽度单位是度。window.innerWidth / window.innerHeight纵横比根据浏览器窗口的宽度和高度计算确保相机适应窗口大小。0.1近裁剪面Near clipping plane即相机能看到的最近物体的距离。1000远裁剪面Far clipping plane即相机能看到的最远物体的距离。 DirectionalLight光源
在Three.js中DirectionalLight 是一种光源它模拟从特定方向发出的平行光类似于太阳光。这种光源的特点是所有从光源发出的光线都是平行的不会随着距离的增加而发散。
DirectionalLight 在这里的作用包括 照亮场景它为场景提供光照使得场景中的物体可以被看到并根据材质属性产生不同的光照效果。 产生阴影DirectionalLight 可以产生阴影效果使得场景更加真实。物体遮挡光线的地方会形成阴影有助于表现物体的立体感和空间位置。 定义光照方向通过设置 DirectionalLight 的位置和方向可以定义光线照射到场景的角度从而影响场景的整体光照效果。 调整光照强度可以通过设置 intensity 属性来调整光线的亮度。
OrbitControls 控制器
Three.js 中的 OrbitControls 是一个控制器它允许用户通过鼠标或触摸事件来控制相机的移动从而实现对场景的旋转、缩放和平移操作。这个控制器使得用户可以更自然地与3D场景交互。 在使用 OrbitControls 时需要注意以下几点 控制器需要与相机和渲染器的DOM元素一起被初始化。在动画循环中调用 controls.update() 方法来确保控制器可以更新相机状态。可以通过修改 OrbitControls 的各种属性来自定义控制行为例如最小/最大缩放距离、旋转限制等。 OrbitControls 是Three.js中非常实用的一个工具它大大简化了3D场景的用户交互开发过程。
以下是 OrbitControls 的一些主要作用 旋转Rotate用户可以通过拖动鼠标来旋转相机从而改变视角。 缩放Zoom通过滚动鼠标滚轮或触摸屏幕进行捏合操作可以放大或缩小场景。 平移Pan通过按下鼠标右键并拖动或者在某些触摸设备上通过特定的手势可以在场景中平移相机。
以下是 OrbitControls 的基本用法
// 引入OrbitControls
import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js;// 创建场景、相机和渲染器
const scene new THREE.Scene();
const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 设置相机位置
camera.position.set(0, 0, 5);// 创建OrbitControls实例并传入相机和渲染器
const controls new OrbitControls(camera, renderer.domElement);// 创建一些对象添加到场景中
// ...// 渲染场景
function animate() {requestAnimationFrame(animate);controls.update(); // 更新控制器renderer.render(scene, camera);
}
animate();position 位置信息
在 Three.js 中position 属性的作用是用于确定 3D 对象在场景中的位置 属性对于实现 3D 场景中对象的布局、动画和交互等方面都非常重要。通过设置对象的 position 属性可以精确地指定该对象在三维空间中的坐标。这使得能够将对象放置在所需的位置从而构建出具有特定布局和结构的 3D 场景。
例如如果要将一个立方体放置在场景的特定点比如 x 坐标为 10y 坐标为 20z 坐标为 30可以这样设置
const geometry new THREE.BoxGeometry();
const material new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube new THREE.Mesh(geometry, material);cube.position.set(10, 20, 30);scene.add(cube);
这样立方体就会出现在指定的位置上。
rotation旋转属性
在 Three.js 中rotation 属性的作用是用于确定 3D 对象在场景中的旋转状态。通过设置对象的 rotation 属性可以精确地指定该对象在三维空间中的旋转角度。这使得能够将对象旋转到所需的方向从而构建出具有特定朝向和视角的 3D 场景。
rotation 属性使用的是欧拉角Euler angles它包括三个分量x、y 和 z分别表示绕 X 轴、Y 轴和 Z 轴的旋转角度以弧度为单位。
例如如果要将一个立方体绕 Y 轴旋转 45 度即 π/4 弧度可以这样设置
const geometry new THREE.BoxGeometry();
const material new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube new THREE.Mesh(geometry, material);cube.rotation.y Math.PI / 4; // 45 degrees in radiansscene.add(cube);requestAnimationFrame实现动画
使用requestAnimationFrame requestAnimationFrame是浏览器提供的API用于在每一帧绘制动画。Three.js中的动画通常通过这个API来实现。
function animate() {requestAnimationFrame(animate);// 更新对象属性例如位置、旋转等cube.rotation.x 0.01;cube.rotation.y 0.01;// 渲染场景renderer.render(scene, camera);
}
animate();
useEffect 在React组件中useEffect 钩子用于处理副作用操作比如数据获取、订阅、手动更改DOM等。useEffect 钩子的主要作用是在组件挂载后将 Three.js 渲染器的 DOM 元素添加到指定的容器中并在组件卸载时进行清理。 组件挂载时添加渲染器 DOM 元素 useEffect 钩子在组件挂载时执行确保 containerRef.current 已经指向了实际的 DOM 元素。通过 containerRef.current.appendChild(renderer.domElement)将 Three.js 渲染器的 DOM 元素添加到指定的容器中。 确保渲染器 DOM 元素正确添加 如果不使用 useEffect直接在组件渲染时添加渲染器 DOM 元素可能会导致 containerRef.current 为 null因为此时 DOM 元素可能还未挂载到页面上。 /*** 创建一个Three.js场景包括相机和渲染器*/
function Robot() {// 创建一个div容器用于存放渲染的Three.js场景const containerRef useRefHTMLDivElement(null);const scene new THREE.Scene();// 创建一个Three.js相机包括透视投影、宽高比、近裁剪面和远裁剪面const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.set(15, 12, 8);camera.lookAt(0, 0, 0);// 创建一个Three.js渲染器包括抗锯齿const renderer new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);const robot generateRobot();const robot2 generateRobot();robot2.position.x 6;robot2.position.z 6;// 将机器人身体添加到场景中scene.add(robot);scene.add(robot2);// 创建一个Three.js方向光包括颜色、强度const straightLight new THREE.DirectionalLight(0xffffff, 5);// 设置方向光的位置straightLight.position.set(5, 5, 10);// 将方向光添加到场景中scene.add(straightLight);const starts generateStarts(200);scene.add(starts);//轨道控制器const controls new OrbitControls(camera, renderer.domElement);controls.update();const update () {requestAnimationFrame(update);robot.rotation.y - 0.005; //机器人旋转robot2.rotation.y - 0.005;// 粒子旋转starts.rotation.y - 0.001;starts.rotation.z 0.001;starts.rotation.x 0.001;renderer.render(scene, camera);};update(); //自动更新// 监听组件挂载和卸载useEffect(() {// 如果div存在将渲染器dom元素添加到div中if (containerRef.current) {containerRef.current.appendChild(renderer.domElement);// 渲染场景renderer.render(scene, camera);}}, [containerRef]);// 返回div容器用于存放渲染的Three.js场景return div ref{containerRef} style{{ width: 100vw, height: 100vh }}/div;
}