こんにちは。
これからThree.jsを使うことになりそうなので、React x TypeScriptでThree.js入門をやっていこうと思います!
# 参考にしたサイト
簡単なThree.jsのサンプルを試そう
超楽しくてカッコいい、Reactで始めるThree.js入門
ReactでThree.jsを使うならreact-three-fiberというライブラリを使ったほうが良いと記事にありましたが、Three.jsの勉強が目的なので、素のThree.jsで実装します。
うまく実装できるとこんな感じの箱が表示されます。
作成したコンポネントのソースコードはこんな感じ。
こちらのサイト(簡単なThree.jsのサンプルを試そう)のソースコードをReact x Typescriptで動くように数か所変更を加えているだけです。
import React, { useEffect } from "react";
import * as THREE from "three";
export const Sample1 = () => {
/** case1 */
const createBox = () => {
// サイズを指定
const width = 960;
const height = 540;
// レンダラを作成
const renderer: any = new THREE.WebGLRenderer({
canvas: document.querySelector("#nyumon-sample1") as HTMLCanvasElement
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成 const camera = new THREE.PerspectiveCamera(45, width / 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);
tick();
// 毎フレーム時に実行されるループイベント
function tick() {
box.rotation.y += 0.01;
renderer.render(scene, camera);
// レンダリング
requestAnimationFrame(tick);
}
};
// didMountで描画しないと、Cannot read property 'width' of nullというエラーが出る
useEffect(() => {
createBox();
}, []);
return (
<>
<h2>入門編 - sample1</h2>
<h3>case1</h3>
<canvas id="nyumon-sample1" />
</>
);
};
詳しい解説はこちらのサイト(簡単なThree.jsのサンプルを試そう)にありますので読んでみてください。
箱を作って描画する大まかな処理の流れは、
step1 – canvasのサイズを指定して、
step2 – レンダラを作成して、
step3 – シーンを作成して、
step4 – カメラを作成して、
step5 – 箱を作成して、
step6 – tickで描画/frameする。
というかんじですね。
自分の印象としては、create.jsにレンダラとカメラが追加されたような感じかなと思います。
参考元のソースコードをコピペしただけだとReactとTypeScriptの方で不具合が出ると思いますので、
ひとつずつエラーを取り除いていきます。
まずはReactの不具合。
描画処理は、useEffectの中で呼び出していますが、
これはcanvas要素mountされた後に描画処理を呼ばないと、Cannot read property ‘width’ of nullというエラーが出るためです。
それとTypeScriptだとレンダラを作成している箇所で型エラーが出ます。// レンダラを作成
const renderer: any = new THREE.WebGLRenderer({
canvas: document.querySelector("#nyumon-sample2")
});// エラーメッセージ
Type 'Element | null' is not assignable to type 'HTMLCanvasElement | OffscreenCanvas | undefined'.
Type 'null' is not assignable to type 'HTMLCanvasElement | OffscreenCanvas | undefined'.
これは、型キャストでエラー回避しました。(正しいのかどうかはワカラナイ)const renderer: any = new THREE.WebGLRenderer({
canvas: document.querySelector("#nyumon-sample2") as HTMLCanvasElement
});
これで無事3Dモデルの初描画に成功しました。
あとはプロパティの値を変えてみたり、箱を200個どうじに表示してみたりして遊ぶだけです。
箱を同時に20000個インスタンス化して描画するとほぼフリーズ状態になりました。
codesandboxでいくつか試してみましたので、よろしければサンプルをご覧になってください。
サンプル
ソースコード付きのサンプル by codesandbox
以上です。