当前位置: 首页 > news >正文

第八部分-周边生态与工具——39. 框架集成

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 Fiber

2.1 安装和导入

npminstallthree @react-three/fiber @react-three/drei
import { 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 Three

3.1 安装和导入

npminstallthree @vue-three/core
<template> <Canvas> <ambientLight :intensity="0.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'; </script>

4. Angular Three

4.1 安装

npminstallthree angular-three
import{Component}from'@angular/core';import{NgtCanvas}from'angular-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 preset="city" /> {/* 物体 */} <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" anchorX="center" anchorY="middle" > 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 转 JSX
@react-three/flex3D 布局
@react-three/postprocessing后期特效

http://www.jsqmd.com/news/763574/

相关文章:

  • 正点原子IMX6ULL SR04模块+Qt使用
  • 别再只调参了!深入解读YOLOv8中BiFPN与P2层的协同作用,让你的模型真正‘看懂’小物体
  • 3大核心策略彻底解决腾讯游戏反作弊进程资源占用问题
  • 别再重复造轮子了!Power Apps组件库保姆级教程,从创建到团队共享一次搞定
  • ollama国内镜像源不可用时的替代方案,使用Taotoken快速接入多模型
  • 从扫地机器人到自动驾驶:聊聊移动机器人规划里那些‘前端搜索’与‘后端优化’的实战门道
  • 创业团队如何用Taotoken低成本试错多个大模型接口
  • 深入MBUS电流调制:用普通运放搭建稳定主站接收电路(含Multisim仿真文件)
  • 2026 年 5 月国内外超声波液位计十大品牌排名 - 仪表人小余
  • 2025届最火的五大AI写作神器横评
  • 免费解锁网盘下载速度:开源直链解析工具完整指南
  • 从Matlab仿真到C代码:PMSM FOC位置环S曲线算法(恒定Jerk)的完整实现流程
  • 5分钟快速上手:明日方舟智能基建管理完整指南
  • 别再用pip install paddle了!手把手教你用conda搞定PaddlePaddle环境(附CUDA版本选择指南)
  • 【Matlab】MATLAB教程:LaTeX与MATLAB结合实操(LaTeX公式生成案例+学术论文专业排版核心应用)
  • 3个技巧让网盘文件下载速度提升5倍:LinkSwift直链解析工具深度解析
  • 别再死磕协议文档了!用Python模拟FiRa UWB测距调度,5分钟搞懂Controller和Controlee怎么对话
  • 解决iOS Safari上的SVG动画问题
  • 【2】深入剖析 Django 之 MTV:配置系统与项目结构
  • 借助快马平台自动化生成代码,高效完成windows18-hd19主题界面开发
  • 开源小说下载器:一键离线阅读100+网站小说内容
  • 599比分算法分析
  • 别再死记硬背了!用Python和NumPy直观理解Voigt符号(附代码示例)
  • 别再扔了!手把手教你用美工刀和砂纸复活‘焊死’的烙铁头(附不同污损等级处理指南)
  • Python 性能分析难题有解!snakeviz 与 profiling - explorer 助力交互式分析
  • 三步掌握PPTist:5大场景教你打造专业在线演示文稿
  • 如何在 MATLAB 中调用 Taotoken 聚合的大模型 API 接口
  • 快速构建js近似数对比工具:用快马平台十分钟搭建浮点数处理演示原型
  • 告别画面一片黑!手把手教你用v4l2-ctl和i2ctransfer调试OV13850摄像头亮度
  • 终极PC多人游戏解决方案:Nucleus Co-Op分屏工具完全指南