react-three-fiber 集成
react-three-fiber(简称 R3F)是一个基于 React 封装 Three.js 的库,它将 Three.js 转换为 React 组件,使开发者可以用 JSX 直接声明 3D 场景,并利用 React 的状态管理、hooks 和组件系统构建复杂的 3D 应用。
从模板开始
建议直接使用集成好的项目模板,它包含了完整的分包优化/代码兼容性配置。
如遇下载失败,你也可以手动到 github 代码仓库根据对应分支下载模板。
npx degit minisheeep/threejs-miniprogram-template#uni-ts-r3f my-projectnpx degit minisheeep/threejs-miniprogram-template#weapp-vite-r3f my-project⚠️注意
由于 weapp-vite 项目的更新迭代较快,破坏性改动较多,请勿随意更新模板内它的版本。
手动集成
安装
pnpm i @minisheep/platform-adapter-integration使用
然后在 vite 和 ts 的配置文件中添加以下内容:
import { defineConfig } from 'vite';
import threePlatformAdapter from '@minisheep/three-platform-adapter/plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
//...
threePlatformAdapter(),
react(),
],
}){
"compilerOptions": {
//...
"jsx": "react"
}
}然后使用包导出的 createRoot 方法将你使用 tresjs 编写的场景组件挂载到画布上。
import { createRoot } from "@minisheep/platform-adapter-integration/r3f";
import { YourScene } from 'path/to/YourScene.tsx'
// ...
await adapter.useCanvas(`#canvas-id`).then(result => {
createRoot(result.canvas).render(<YourScene/>);
// ...
});相关函数声明如下。
import type { ReactNode } from 'react';
export declare function createRoot(canvas: HTMLCanvasElement): {
render(reactElement: ReactNode, callback?: (() => void) | null): any;
unmount(callback?: () => void): void;
};需要注意的是,挂载的场景组件需要满足如下要求:
- 只有一个 R3F 的
Canvas根节点 - 禁止包含其他小程序元素
例如:
import { Canvas } from '@react-three/fiber'
export function YourFirstScene() {
return (
<Canvas>
<mesh>
<torusGeometry args={[1, 0.5, 16, 32]}/>
<meshBasicMaterial color="orange"/>
</mesh>
<ambientLight intensity={1}/>
</>
);
}完整的代码你可以参考此模板。
在 uni-app 中使用
在 uni-app 中集成 tresjs 显得有些特别,因为 uni-app 基于 vue 生态,而 R3F(React Three Fiber)属于 react 体系, 尽管如此,R3F 所具备的一些优势依然值得关注:
- 相较于
tres.js,R3F更加成熟稳定。 - 拥有更活跃的社区和丰富的使用场景示例。
但这也带来了一些挑战:
- 你需要额外引入
react的核心依赖,这将显著增加包体积。
配置以支持 react-jsx
你仅需在 vite.config.ts 中添加以下配置,否则 uni 会拦截 jsx 的相关处理
import { defineConfig } from 'vite';
import threePlatformAdapter from '@minisheep/three-platform-adapter/plugin';
import react from '@vitejs/plugin-react';
import { supportR3fInUni } from '@minisheep/platform-adapter-integration/r3f/plugin';
export default defineConfig({
plugins: [
//...
threePlatformAdapter(),
react(),
supportR3fInUni(),
],
})⚠️注意
这个插件可能会破坏 uni 处理 jsx 的能力(仅构建小程序目标的用户不影响)。
额外处理
如果你需要使用 @react-three/drei 提供的 Text 组件,还需通过 @minisheep/troika-three-text 来强制覆盖默认的 troika-three-text 包。 该版本修复了一些兼容性问题,使其在特定环境中能够正常运行。
在 package.json 中添加如下配置:
{
"pnpm": {
"overrides": {
"troika-three-text": "npm:@minisheep/troika-three-text@^0.52.4"
}
}
}{
"overrides": {
"troika-three-text": "npm:@minisheep/troika-three-text@^0.52.4"
}
}{
"resolutions": {
"troika-three-text": "npm:@minisheep/troika-three-text@^0.52.4"
}
}同时,还需要手动禁用该库的 worker 功能:
import { configureTextBuilder } from 'troika-three-text';
configureTextBuilder({
useWorker: false, // 必须禁用 worker,否则会导致运行异常
});