💡
@react-three/dreiって、TypeScriptじゃ動かんくね?00x(Stats, OrbitControls)
Abstract
@react-three/dreiのサンプルコード、JavaScriptだと結構あるけど、TypeScriptだと全然ない。JavaScriptから興すとビルドエラーやし。
どげんか動かしたる。
今回はこれ。
結論
今回の成果物はココ↓
前提
- React+Typescriptの開発環境は構築済 Ubuntu22.04+VSCode+React+TypeScriptの開発環境を構築してみた。
- めんどいから、これを使う。
前準備
1.プロジェクト生成 -> VSCodeで開く
めんどいから、これ→React-Ts-Templateを雛形にする。
で、下記コマンドでフォルダ名とか整備する。
フォルダリネームとか
$ BaseProject=React-Ts-Template
$ NewProject=react-drei-react-typescript
$ cd ~
$ git clone https://github.com/aaaa1597/${BaseProject}.git
$ rm -rf ${BaseProject}/.git
$ rm -rf ${react}
$ mv ${BaseProject} ${react}
2.生成したプロジェクトの場所でthree.jsとかR3Fとかインストール
$ cd ~
$ cd react-drei-react-typescript
$ npm install
$ npm install --save three
$ npm install --save @types/three
$ npm install --save @react-three/fiber
$ npm install --save @react-three/drei
App.tsxを作っていく
App.tsxの全体
App.tsx
-import React from 'react';
+import React, { Suspense, useRef } from 'react';
+import { Canvas, ThreeElements, useFrame } from "@react-three/fiber";
+import { Stats, OrbitControls } from "@react-three/drei";
+import * as THREE from "three";
import './App.css';
+const Cube = () => {
+ const cube = useRef<THREE.Mesh>(null!)
+
+ useFrame(() => {
+ cube.current!.rotation.x += 0.01;
+ cube.current!.rotation.y += 0.01;
+ });
+
+ return (
+ <mesh ref={cube}>
+ <boxGeometry args={[3, 3, 3]} />
+ <meshBasicMaterial color="#0391BA" />
+ </mesh>
+ );
+};
+const Scene = () => {
+ return (
+ <>
+ <gridHelper />
+ <axesHelper />
+ <pointLight intensity={1.0} position={[5, 3, 5]} />
+ <Cube />
+ </>
+ );
+};
-function App() {
+const App = () => {
return (
- <div className="App">
- hello world!!
+ <div style={{ height: "75vh", width: "75vw"}}>
+ <Canvas camera={{ near: 0.1, far: 1000, zoom: 1 }} onCreated={({ gl }) => {gl.setClearColor("#227700") }}>
+ <Stats />
+ <OrbitControls />
+ <Suspense fallback={null}>
+ <Scene />
+ </Suspense>
+ </Canvas>
</div>
);
}
export default App;
出来た!!
ポイント
1.<Stats/>
統計情報(fpsとか)を表示してくれるやつ。
dreiをインストールとimportしとく必要がある。
↓これ
2.dreiをimportする発生するエラー。
↓こいつに苦しんだ。
App.tsx
- const cube = useRef<THREE.Mesh>()
+ const cube = useRef<THREE.Mesh>(null!)
引数に"null!"を追加すれば直ったけど、エラーが全然分かんない。
こんなエラー出ても分かんねーよ。初心者に優しくない。
エラーの内容
ERROR in src/App.tsx:16:11
TS2322: Type 'MutableRefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined>' is not assignable to type 'Ref<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap>> | undefined'.
Type 'MutableRefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined>' is not assignable to type 'RefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap>>'.
Types of property 'current' are incompatible.
Type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined' is not assignable to type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | null'.
Type 'undefined' is not assignable to type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | null'.
14 |
15 | return (
> 16 | <mesh ref={cube}>
| ^^^
17 | <boxGeometry args={[3, 3, 3]} />
18 | <meshBasicMaterial color="#0391BA" />
19 | </mesh>
3.<OrbitControls />
マウスの動きに合わせて、視点をグリグリ変えてくれるやつ。
詳細はこっち。
4.<Suspense/>
ロード中の待ち画面を表示してくやつ。詳細はこっち。
App.tsx
<Suspense fallback={<div>ロード中はこれが表示される</div>}>
<MyComponent />
</Suspense>
5.<gridHelper />
格子状の板を表示してくれるやつ。オブジェクトの位置を確認しやすくなる。
6.<axesHelper />
3軸の線を表示してくれるやつ。回転状況が分かりやすくなる。
以上。
Discussion