使用 react-three-fiber 快速重构 Three.js 场景⚛️

不明白的知识先放在一边,激发兴趣是第一步,所以不必纠结代码的细节,相信我你很快就会爱上这种感觉!!!

今天,我们将更进一步,将上一篇中vite + npm传统 Three.js 原生代码完整 重构为 react-three-fiber 风格

本文将带你完成以下目标:

  • ✅ 使用 React 重构原生 Three.js 场景
  • ✅ 拆分组件化结构,实现同样效果
  • ✅ 保留交互、动画、响应式特性

推荐网站地址
官方文档https://r3f.docs.pmnd.rs/getting-started
优秀中文文档https://fiber.framer.wiki/Introduction

🌟 为什么选择 react-three-fiber?

react-three-fiber 是一个将 Three.js 映射为 React 声明式组件的库,优点包括:

  • ✅ 完全响应式、组合式
  • ✅ 更容易重用组件
  • ✅ 支持 Suspense、hooks、reactivity 等 React 特性
  • ✅ 社区活跃,生态丰富(如 drei、leva、postprocessing 等)

📦 创建项目 & 安装依赖

npm create vite@latest r3f-demo --template react

cd r3f-demo

npm install

npm install three @react-three/fiber @react-three/drei

📁 项目结构推荐

src/
├── App.jsx
├── components/
│   ├── Dodecahedron.jsx
│   ├── BaseBox.jsx
│   └── Lights.jsx
└── main.jsx

🎮 主组件 App.jsx

import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import Dodecahedron from './components/Dodecahedron';
import BaseBox from './components/BaseBox';
import Lights from './components/Lights';

export default function App() {
  return (
    <Canvas
      camera={{ position: [0, 0, 5], fov: 75 }}
      style={{ width: '100vw', height: '100vh' }}
    >
      <color attach="background" args={['#f0f0f0']} />
      <Lights />
      <Dodecahedron />
      <BaseBox />
      <OrbitControls enableDamping dampingFactor={0.05} />
    </Canvas>
  );
}

🎲 十二面体组件 Dodecahedron.jsx

import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';

export default function Dodecahedron() {
  const ref = useRef();

  useFrame(() => {
    ref.current.rotation.x += 0.01;
    ref.current.rotation.y += 0.01;
  });

  return (
    <mesh ref={ref}>
      <dodecahedronGeometry />
      <meshLambertMaterial
        color="#468585"
        emissive="#468585"
      />
    </mesh>
  );
}

🟫 底座方块组件 BaseBox.jsx

import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';

export default function BaseBox() {
  const ref = useRef();

  useFrame(() => {
    ref.current.rotation.y += 0.01;
  });

  return (
    <mesh ref={ref} position={[0, -1.5, 0]}>
      <boxGeometry args={[2, 0.1, 2]} />
      <meshLambertMaterial
        color="#b4b4b3"
        emissive="#b4b4b3"
      />
    </mesh>
  );
}

💡 灯光组件 Lights.jsx

export default function Lights() {
  return (
    <>
      <ambientLight intensity={0.3} />
      <spotLight
        color="#006769"
        intensity={100}
        position={[1, 1, 1]}
        castShadow
      />
    </>
  );
}

🎉 完整效果

你现在应该能看到:

  • 一个旋转的 十二面体

  • 一个缓慢转动的 底座

  • 柔和背景光与 聚光灯打亮对象

  • OrbitControls 支持拖拽、缩放、平移

  • 窗口缩放自动适配 ✅

效果与原生写法完全一致,但代码组织更清晰,扩展性更强 🧩

当然你可以直接在我分享的stackblitz中直接尝试更改一些代码,以获得不同的效果。

演示地址:https://stackblitz.com/edit/vitejs-vite-awnvthyl?file=src%2Fcomponents%2FBaseBox.jsx 💻

react-r3f

📌 小结

今天我们在保留原始功能和视觉效果的前提下,体验如何在 React 世界中优雅重建:

  • 🎲 使用十二面体(DodecahedronGeometry
  • 🎁 加一个带有旋转的方形底座
  • 💡 添加聚光灯
  • 🖱️ 支持轨道控制器(OrbitControls)
  • 🎥 响应式相机 + 窗口缩放适配
  • ✨ 使用现代组件拆分方式组织项目结构

🔮 下一篇预告:3D 个人主页实战 · 第一部分


在接下来的系列中,我们将打造一个 交互式的 3D 个人主页,内容包括:
  • 📦 准备 3D 模型资源

  • 🏗️ 搭建场景结构骨架

  • 🚪各种准备工作

敬请期待 👀

个人主页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值