株式会社マリエッタ

react.js x TypeScriptでThree.jsを試す

622 views

こんにちは。
これから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
以上です。

Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks
Pinterest
Pocket
Evernote
Feedly
Send to LINE