🤖
React+TypeScriptなWebアプリで、three.jsの3D表示の最初の一歩。"React Three Fiber"なしで。
Abstract
React+Typescriptでthree.jsを試してみたかったというモチベーションで。
最初の一歩として、立方体を表示させてみた。
Reactには、"React Three Fiber"って素晴らしかライブラリがあるとですけど、今回はあえて使わず。
環境構築~3D表示まで。
結論
今回の成果物はココ↓
前提
- React+Typescriptの開発環境は構築済 Ubuntu22.04+VSCode+React+TypeScriptの開発環境を構築してみた。
- 空っぽプロジェクトにしててね。React+TypeScriptのプロジェクト雛形をgithubに置いとく話。
手順
1.プロジェクト生成 -> VSCodeで開く
めんどいから、プロジェクト雛形をgithubから持ってくる。React+TypeScriptのプロジェクト雛形をgithubに置いとく話。
で、下記コマンドでフォルダ名とか整備する。
フォルダリネームとか
$ ProjectName=react-threejs-1ststep
$ cd ~
$ git clone https://github.com/aaaa1597/React-Ts-Template.git
$ rm -rf React-Ts-Template/.git
$ rm -rf ${ProjectName}
$ mv React-Ts-Template ${ProjectName}
2.生成したプロジェクトの場所でthree.jsをインストール
$ cd プロジェクトのフォルダ
$ npm install
$ npm install --save three
$ npm install @types/three
App.tsxを作っていく
1.描画領域(<canvas />)を生成
App.tsx <canvas />生成
-import React from 'react';
+import React, { useEffect, useRef } from 'react';
import './App.css';
+import * as THREE from 'three';
+// サイズを指定
+const DISPLAY_WIDTH = 960;
+const DISPLAY_HEIGHT = 540;
-function App() {
+const App = () => {
+ const canvasRef = useRef<HTMLCanvasElement>(null);
+ useEffect(() => {
+ //レンダラーを作成
+ const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer({
+ canvas: canvasRef.current??undefined,
+ });
+ renderer.setPixelRatio(window.devicePixelRatio);
+ renderer.setSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ }, [])
return (
<div className="App">
+ <canvas width={DISPLAY_WIDTH} height={DISPLAY_HEIGHT} ref={canvasRef} />
hello world!!
</div>
);
}
export default App;
まだ空っぽ。なんとなくcanvasが配置されているのが見える。
2.シーン、カメラ、モデル(今回はBOX)を生成
シーン、カメラ、モデルは、three.js独特だ。要はこれらを毎フレーム変更すればいいんだな。
ふ~ん。
App.tsx シーン、カメラ、モデルを生成
~ 略 ~
// サイズを指定
const DISPLAY_WIDTH = 960;
const DISPLAY_HEIGHT = 540;
const App = () => {
~ 略 ~
useEffect(() => {
~ 略 ~
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ // シーンを作成
+ const scene = new THREE.Scene();
+ // カメラを作成
+ const camera = new THREE.PerspectiveCamera(45, DISPLAY_WIDTH / DISPLAY_HEIGHT);
+ camera.position.set(0, 0, +1000);
+ // 箱を作成
+ const geometry = new THREE.BoxGeometry(400, 400, 400);
+ const material = new THREE.MeshNormalMaterial();
+ const box = new THREE.Mesh(geometry, material);
+ scene.add(box);
}, [])
~ 略 ~
まだ空っぽ。そりゃそうだ。定義はしたけど、描画はしてないもんね。
3.描画を生成
描画関数を作って、呼ぶ。
App.tsx 描画
~ 略 ~
const App = () => {
~ 略 ~
const geometry = new THREE.BoxGeometry(400, 400, 400);
const material = new THREE.MeshNormalMaterial();
const box = new THREE.Mesh(geometry, material);
scene.add(box);
+ const tick = () => {
+ box.rotation.y += 0.01
+ renderer.render(scene, camera)
+ requestAnimationFrame(tick);
+ }
+
+ /* 初回起動 */
+ tick()
}, [])
~ 略 ~
出来た!!
意外に簡単。
WebGLって聞いてたから、もっと初期化が複雑かと思ってた。
Discussion