使用 react-three-fiber 深入 React 和 Three.js
已發表: 2022-03-10react-three-fiber
是一個強大的 Three.js 渲染器,可以幫助渲染 React 及其原生應用程序的 3D 模型和動畫。 在本教程中,您將學習如何在 React 應用程序中配置和構建 3D 模型。 今天,我們將學習如何配置和使用react-three-fiber
在 React 和 React Native 應用程序中構建和顯示 3D 模型和動畫。
本教程適用於想要了解更多關於使用 React 的 Web 中的 3D 模型動畫的開發人員,以及任何對 Three.js 有限制(例如無法創建畫布、綁定用戶事件(如click
事件)和啟動渲染循環、 react-three-fiber
)的人react-three-fiber
帶有這些方法。 我們將構建一個 3D 模型,以更好地了解如何使用react-three-fiber
構建 Three.js 3D 模型。
react-three-fiber
入門
Three.js 是一個可以更輕鬆地在瀏覽器中創建 3D 圖形的庫,它使用畫布 + WebGL 來顯示 3D 模型和動畫,您可以在此處了解更多信息。
react-three-fiber 是 web 上 Three.js 和 react-native 的 React 渲染器,它提高了使用 Three.js 創建 3D 模型和動畫的速度,一些具有 3D 模型和動畫的網站示例可以在這裡找到。 react-three-fiber
減少了在動畫上花費的時間,因為它具有可重用的組件、綁定事件和渲染循環,首先我們來看看 Three.js 是什麼。
react-three-fiber
允許我們使用 React 狀態、鉤子和道具構建threeJS
代碼的組件,它還帶有以下元素:
元素 | 描述 |
---|---|
mesh | 有助於定義模型形狀的屬性 |
hooks | react-three-fiber 定義了幫助我們編寫函數來幫助定義用戶事件的鉤子,例如onClick 和onPointOver |
基於組件和渲染循環 | react-three-fiber 是基於組件的,根據狀態或存儲的變化進行渲染 |
如何使用react-three-fiber
要使用react-three-fiber
,首先使用以下命令:
新PM
npm i three react-three-fiber
紗
yarn add three react-three-fiber
注意:要讓react-three-fiber
工作,你需要像我們上面那樣安裝three
(Three.js)。
構建 React 3D Ludo Dice 模型和動畫項目
在這裡,我們將使用react-three-fiber
構建一個 3D 骰子模型,就像我們在下面的視頻中一樣。
我們將使用create-react-app
來初始化我們的項目,為此讓我們在終端上執行以下命令。
create-react-app react-three-fiber-ludo-model
上面的命令在我們的本地機器中初始化了一個 React 項目,接下來讓我們cd
進入目錄並安裝我們的包react-three-fiber
和three
。
cd react-three-fiber-ludo-model npm i three react-three-fiber
一旦安裝了軟件包,讓我們使用命令啟動我們的開發服務器
npm start
上面的命令應該在我們的瀏覽器中啟動我們的項目開發服務器。 接下來讓我們在我們選擇的文本編輯器中打開我們的項目,在我們的項目src
文件夾中,刪除以下文件: App.css
、 App.test.js
、 serviceWorker.js
和setupTests.js
。 接下來,讓我們刪除所有引用App.js
上已刪除文件的代碼。
對於這個項目,我們將需要一個Box
組件用於我們的 Ludo 骰子和由 React 提供的App
組件。
構建Box
組件
Box
組件將包含我們的ludo 骰子的形狀、ludo 骰子的圖像和始終保持旋轉的狀態。 首先,讓我們為下面的Box
組件導入我們需要的所有包。
import React, { useRef, useState, useMemo } from "react"; import { Canvas, useFrame } from "react-three-fiber"; import * as THREE from "three"; import five from "./assets/five.png";
在上面的代碼中,我們導入useRef
、 useState
和useMemo
。 我們將使用useRef
鉤子來訪問骰子的網格,並使用useState
鉤子來檢查 ludo 骰子的活動狀態。 useMemo
鉤子將用於返回骰子上的數字。 接下來,我們從react-three-fiber
導入Canvas
和useFrame
, canvas
用於在瀏覽器上繪製圖形,而useFrame
允許組件掛鉤到渲染循環,這使得一個組件可以渲染另一個的內容。 接下來,我們導入了這three
包,然後我們導入了一個盧多骰子的靜態圖像。
接下來是為我們的Box
組件編寫邏輯。 首先,我們將從構建一個功能組件開始,並為我們的組件添加狀態,讓我們在下面這樣做。
const Box = (props) => { const mesh = useRef(); const [active, setActive] = useState(false); useFrame(() => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01; }); const texture = useMemo(() => new THREE.TextureLoader().load(five), []); return ( <Box /> ); }
在上面的代碼中,我們創建了一個帶有 props 的Box
組件,接下來我們使用useRef
鉤子創建了一個名為mesh
的引用,這樣做是為了每次都可以返回相同的網格。
網格是場景中的視覺元素,它是構成三角形多邊形的 3D 對象,它通常使用Geometry構建,用於定義模型的形狀, Material用於定義模型的外觀,您可以在此處了解 Mesh,您還可以在此處了解有關useRef
掛鉤的更多信息。
初始化mesh
後,我們需要使用useState
鉤子為我們的應用程序初始化一個狀態,這裡我們將應用程序的懸停和活動狀態設置為 false。
接下來,我們使用react-three-fiber
中的useFrame
鉤子來旋轉網格(ludo dice),使用下面的代碼
mesh.current.rotation.x = mesh.current.rotation.y += 0.01;
在這裡,我們每 0.01 秒旋轉一次網格的當前位置,這樣做是為了給旋轉一個好的動畫。
const texture = useMemo(() => new THREE.TextureLoader().load(five), []);
在上面的代碼中,我們創建了一個名為texture
的常量,並傳入一個 react useMemo
鉤子作為函數來加載一個新的擲骰子,這裡使用useMemo
來記憶骰子圖像及其編號。 你可以在這裡了解useMemo
鉤子。
接下來,我們要在瀏覽器上渲染Box
組件並添加我們的事件,我們在下面這樣做
const Box = (props) => { return ( <mesh {...props} ref={mesh} scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]} onClick={(e) => setActive(!active)} > <boxBufferGeometry args={[1, 1, 1]} /> <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}> <primitive attach="map" object={texture} /> </meshBasicMaterial> </mesh> ); }
在上面的代碼中,我們返回了我們的Box
組件並將其包裝在mesh
中,我們使用擴展運算符傳遞了Box
組件的所有屬性,然後我們使用useRef
掛鉤引用了網格。 接下來,我們使用 Three.js 中的scale
屬性來設置骰子框的大小,當它處於活動狀態時為 2 和 1.5,當它不處於活動狀態時。 最後但並非最不重要的一點是,我們添加了一個onClick
事件以將state
設置為active
,如果它未設置為默認值。
<boxBufferGeometry args={[1, 1, 1]} />
為了渲染骰子盒子,我們從 Three.js 中渲染了boxBufferGeometry
組件, boxBufferGeometry
幫助我們繪製了諸如盒子之類的線和點,我們使用args
參數來傳遞諸如盒子幾何尺寸之類的構造函數。
<meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}>
meshBasicMaterial
中的 meshBasicMaterial 用於以簡單的形式繪製幾何圖形。 在這裡,我們傳遞了attach
屬性並將THREE.DoubleSide
道具傳遞給side
屬性。 THREE.DoubleSide
定義了應該由react-three-fiber
渲染的邊或空間。
<primitive attach="map" object={texture} />
Three.js 的primitive
組件用於繪製 3D 圖形。 我們附加了 map 屬性以保持 Ludo 骰子的原始形狀。 接下來,我們將在App.js
文件中渲染我們的Box
組件並完成我們的 3d ludo 骰子框。 您的組件應該類似於下圖。
渲染 3D Ludo 骰子盒
在本節中,我們將在App.js
中渲染我們的Box
組件並完成我們的 3d ludo 框,首先,讓我們創建一個App
組件並用Canvas
標籤包裝它,這是為了渲染我們的 3D 模型,讓我們在下面這樣做。
const App = () => { return ( <Canvas> </Canvas> ); } export default App;
接下來,讓我們為盒子添加一個燈光, react-three-fiber
為我們提供了三個組件來點亮我們的模型,它們如下
ambientLight
這用於均勻地照亮場景或模型中的所有對象,它接受諸如光強度之類的道具,這將照亮盧多骰子的主體。-
spotLight
這種光是從一個方向發出的,它隨著物體大小的增加而增加,這將照亮盧多骰子的點。 -
pointLight
這類似於燈泡的光,光從一個點發射到各個方向,這對於我們的應用程序的活動狀態是必要的。
讓我們在下面的應用程序中實現上述內容。
const App = () => { return ( <Canvas> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} /> <pointLight position={[-10, -10, -10]} /> </Canvas> ); } export default App;
在上面的代碼中,我們從react-three-fiber
導入了環境光組件,並pointLight
添加了 0.5 的強度,接下來我們為我們的spotLight
和ambientLight
組件添加了位置和角度。 我們應用程序的最後一步是渲染我們的盒子組件並為 ludo 骰子盒子添加一個位置,我們將在下面的代碼中這樣做
<Box position={[-1.2, 0, 0]} /> <Box position={[2.5, 0, 0]} />
完成後,您的 Ludo 3D 骰子應類似於下圖:
CodeSandbox 上提供了一個工作演示。
結論
react-three-fiber
使得渲染 3D 模型和動畫更容易為 React 和 React Native 應用程序創建。 通過構建我們的 3D 骰子盒,我們了解了 Three.js 的基礎知識以及react-three-fiber
的組件和優點以及如何使用它。
您可以通過自己使用react-three-fiber
在您的 React 和 Native 應用程序中構建 3D 模型和動畫來進一步實現這一點。 我很想看看你想出了什麼新東西!
您可以在下面的參考資料中閱讀有關 Three.js 和react-three-fiber
的更多信息。
相關資源
- 三.js 文檔
- 三.js 基礎
- Poimandres 的 React-Three-Fiber GitHub 存儲庫
- 反應三纖維文檔
- React Hooks(useState、useMemo等)官方文檔