
39. 框架集成1. 概述框架集成将 Three.js 与前端框架React、Vue、Angular、Svelte结合提供组件化的 3D 开发体验。React Three Fiber 是最流行的 Three.js React 渲染器。┌─────────────────────────────────────────────────────────────┐ │ 框架集成生态 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ React Three Fiber │ │ ├── 特点React 组件化 │ │ ├── 语法JSX 描述 3D 场景 │ │ ├── 生态react-three/fiber, react-three/drei │ │ └── 适用React 项目 │ │ │ │ Vue Three │ │ ├── 特点Vue 3 组合式 API │ │ ├── 语法模板 组件 │ │ ├── 生态vue-three │ │ └── 适用Vue 3 项目 │ │ │ │ Angular Three │ │ ├── 特点Angular 指令 │ │ ├── 语法模板指令 │ │ ├── 生态angular-three │ │ └── 适用Angular 项目 │ │ │ └─────────────────────────────────────────────────────────────┘2. React Three Fiber2.1 安装和导入npminstallthree react-three/fiber react-three/dreiimport { Canvas } from react-three/fiber; import { OrbitControls, Box, Sphere } from react-three/drei; function App() { return ( Canvas ambientLight intensity{0.5} / directionalLight position{[5, 10, 7]} / Box position{[-1, 0, 0]} meshStandardMaterial color#ff6600 / /Box Sphere position{[1, 0, 0]} meshStandardMaterial color#44aa88 / /Sphere OrbitControls / /Canvas ); }2.2 组件化import { Canvas, useFrame } from react-three/fiber; import { useRef, useState } from react; function RotatingCube() { const meshRef useRef(); const [hovered, setHovered] useState(false); useFrame(() { meshRef.current.rotation.x 0.01; meshRef.current.rotation.y 0.01; }); return ( mesh ref{meshRef} onPointerOver{() setHovered(true)} onPointerOut{() setHovered(false)} boxGeometry args{[1, 1, 1]} / meshStandardMaterial color{hovered ? #ff6600 : #44aa88} / /mesh ); } function App() { return ( Canvas ambientLight intensity{0.5} / pointLight position{[10, 10, 10]} / RotatingCube / /Canvas ); }2.3 加载模型import { useGLTF } from react-three/drei; function Model({ url }) { const { scene } useGLTF(url); return primitive object{scene} scale{0.5} /; } function App() { return ( Canvas ambientLight intensity{0.5} / directionalLight position{[5, 10, 7]} / Model url/models/character.glb / OrbitControls / /Canvas ); }2.4 动画和状态import { Canvas, useFrame } from react-three/fiber; import { useRef, useState } from react; function AnimatedSphere() { const meshRef useRef(); const [active, setActive] useState(false); useFrame((state, delta) { meshRef.current.rotation.y 0.01; if (active) { meshRef.current.scale.x 1 Math.sin(state.clock.elapsedTime * 5) * 0.2; meshRef.current.scale.y 1 Math.sin(state.clock.elapsedTime * 5) * 0.2; meshRef.current.scale.z 1 Math.sin(state.clock.elapsedTime * 5) * 0.2; } }); return ( mesh ref{meshRef} onClick{() setActive(!active)} position{[0, 0, 0]} sphereGeometry args{[1, 64, 64]} / meshStandardMaterial color{active ? #ff6600 : #44aa88} / /mesh ); }3. Vue Three3.1 安装和导入npminstallthree vue-three/coretemplate Canvas ambientLight :intensity0.5 / directionalLight :position[5, 10, 7] / mesh :position[-1, 0, 0] boxGeometry :args[1, 1, 1] / meshStandardMaterial color#ff6600 / /mesh mesh :position[1, 0, 0] sphereGeometry :args[0.8, 64, 64] / meshStandardMaterial color#44aa88 / /mesh OrbitControls / /Canvas /template script setup import { Canvas, OrbitControls } from vue-three/core; /script4. Angular Three4.1 安装npminstallthree angular-threeimport{Component}fromangular/core;import{NgtCanvas}fromangular-three;Component({selector:app-scene,template:ngt-canvas ngt-ambient-light [intensity]0.5 / ngt-directional-light [position][5, 10, 7] / ngt-mesh [position][-1, 0, 0] ngt-box-geometry [args][1, 1, 1] / ngt-mesh-standard-material color#ff6600 / /ngt-mesh ngt-mesh [position][1, 0, 0] ngt-sphere-geometry [args][0.8, 64, 64] / ngt-mesh-standard-material color#44aa88 / /ngt-mesh ngt-orbit-controls / /ngt-canvas})exportclassSceneComponent{}5. 完整示例import React, { useState, useRef, Suspense } from react; import { Canvas, useFrame } from react-three/fiber; import { OrbitControls, useGLTF, Html, Text, Environment } from react-three/drei; import * as THREE from three; // 旋转立方体组件 function RotatingCube({ position, color }) { const meshRef useRef(); const [hovered, setHovered] useState(false); useFrame((state) { meshRef.current.rotation.x 0.01; meshRef.current.rotation.y 0.01; }); return ( mesh ref{meshRef} position{position} onPointerOver{() setHovered(true)} onPointerOut{() setHovered(false)} castShadow boxGeometry args{[1, 1, 1]} / meshStandardMaterial color{hovered ? #ff6600 : color} metalness{0.5} roughness{0.3} / /mesh ); } // 旋转球体组件 function RotatingSphere({ position, color }) { const meshRef useRef(); useFrame((state) { meshRef.current.rotation.y 0.01; meshRef.current.scale.x 1 Math.sin(state.clock.elapsedTime * 2) * 0.1; meshRef.current.scale.y 1 Math.sin(state.clock.elapsedTime * 2) * 0.1; meshRef.current.scale.z 1 Math.sin(state.clock.elapsedTime * 2) * 0.1; }); return ( mesh position{position} ref{meshRef} castShadow sphereGeometry args{[0.8, 64, 64]} / meshStandardMaterial color{color} metalness{0.5} roughness{0.3} / /mesh ); } // 地面组件 function Ground() { return ( mesh rotation{[-Math.PI / 2, 0, 0]} position{[0, -1, 0]} receiveShadow planeGeometry args{[10, 10]} / meshStandardMaterial color#336699 side{THREE.DoubleSide} / /mesh ); } // 模型加载组件 function ModelViewer({ url, position, scale 1 }) { const { scene } useGLTF(url); return primitive object{scene} position{position} scale{scale} /; } // 主应用 function App() { const [showModel, setShowModel] useState(false); return ( div style{{ width: 100vw, height: 100vh }} Canvas shadows camera{{ position: [5, 5, 8], fov: 45 }} {/* 光源 */} ambientLight intensity{0.5} / directionalLight position{[5, 10, 7]} intensity{1} castShadow shadow-mapSize-width{1024} shadow-mapSize-height{1024} / pointLight position{[2, 3, 4]} intensity{0.5} / {/* 辅助 */} OrbitControls enableDamping / Environment presetcity / {/* 物体 */} RotatingCube position{[-2, 0, 0]} color#ff6600 / RotatingSphere position{[0, 0, 0]} color#44aa88 / RotatingCube position{[2, 0, 0]} color#88aaff / {/* 地面 */} Ground / {/* 3D 文字 */} Text position{[0, 1.5, 0]} fontSize{0.5} color#ffffff anchorXcenter anchorYmiddle React Three Fiber /Text {/* 模型加载 */} {showModel ( Suspense fallback{null} ModelViewer url/models/character.glb position{[0, 0, 2]} scale{0.5} / /Suspense )} {/* HTML 覆盖层 */} Html position{[0, -1.2, 0]} div style{{ background: rgba(0,0,0,0.7), padding: 8px, borderRadius: 4px, color: white }} 3D 场景 /div /Html /Canvas {/* UI 控制 */} div style{{ position: absolute, bottom: 20px, left: 20px, background: rgba(0,0,0,0.7), padding: 10px, borderRadius: 5px, color: white, zIndex: 100 }} button onClick{() setShowModel(!showModel)} style{{ padding: 8px 16px, background: #ff6600, border: none, borderRadius: 4px, color: white, cursor: pointer }} {showModel ? 隐藏 : 显示}模型 /button /div /div ); } export default App;6. 框架对比框架库学习曲线生态适用场景ReactR3F中等丰富React 项目Vuevue-three中等一般Vue 项目Angularangular-three较高一般Angular 项目Sveltesvelte-cubed低较小Svelte 项目7. 总结库用途react-three/fiberReact 渲染器react-three/drei辅助组件react-three/gltfjsxglTF 转 JSXreact-three/flex3D 布局react-three/postprocessing后期特效