WebGL開発環境を整える(Parcel + TypeScript + Three.js)

January 09, 2020

TypeScript を使った Three.js の開発環境を構築してみました。

最終的なソースコードはこちらに置きました。

sandbox/three-js at master · SatoshiKawabata/sandbox · GitHub

Parcelを使う

モジュールバンドラにはParcelを使います。とりあえずTypeScriptとWebGLが動く環境が欲しかったのでWebpackを使うまでもないかなと思いParcelを使いました。

Parcel

インストール

npm install -D parcel-bundler

HTML、TypeScriptの準備

Parcelの起動htmlファイルsrc/index.htmlを作成する。index.tsを読み込むようにします。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Hello</title>
  </head>
  <body>
    <script src="./index.ts"></script>
  </body>
</html>

TypeScriptファイルsrc/index.tsを作成する。ただhelloと出力されるだけのTypeScriptです。

console.log("hello");

起動

下記コマンドでdevサーバが起動します。http://localhost:1234にアクセスしてコンソールにhelloと出力されていれば成功です。

npx parcel src/index.html

WebGL(Three.js)環境を整える

今回はThree.jsを使います。

three.js – JavaScript 3D library

githubのリポジトリです。

GitHub - mrdoob/three.js: JavaScript 3D library.

インストール

npm i --save three

TypeScript内でimportする。これだけで完了です。型定義ファイルも必要になるかなと思っていたのですが、three.jsライブラリ自体が型定義を持っているようです。

import * as THREE from "three";
console.log("hello", THREE);

threeではなくthree-jsモジュールのほうを使う?

こちらの記事を見ていると、下記のような記述がありました。threeモジュールにはaddonが入っていないみたいです。three-jsを使えばaddonも使えるとのこと。three.js自体のバージョンは少し古くなってしまうようです。

webpack + typescriptな環境でthree.jsのexampleを使う - Qiita

困っていたところnpmにthreeではなくthree-jsというパッケージを見つけた three-js どうやら拡張も含めて入っていて簡単に含めることができるよう.

どれだけ古くなるのかと思い、調べてみるとバージョン79を使っているようです。最新のThree.jsのバージョンは112ですのでだいぶ古い…。

GitHub - JordanDelcros/npm-three-js: Make three-js and its addons available for npm

バージョンがあまりにも古いのでちょっとこれを使うのはやめておきます。

サンプルの実行

今回はこちらのサンプルのソースコードを動かしてみることにします。

【Three.js】360°パノラマビューワーを作ってグリグリ操作出来るようにした(スマホ対応) - Qiita

addon three-orbitcontrols-tsのインストール

addonがないという下記エラーが出たのでインストールします。

three.jsのOrbitControlsをTypescriptで使う方法 - Qiita

Property 'OrbitControls' does not exist

three-orbitcontrols-tsをインストール

three-orbitcontrols-ts

npm i three-orbitcontrols-ts

ソースコード

最終的なソースコードはこんな感じになりました。

import * as THREE from "three";
import { OrbitControls } from "three-orbitcontrols-ts";
const testImage = require("./images/test.jpg");

const width = window.innerWidth;
const height = window.innerHeight;
const scene = new THREE.Scene();

// mesh
const geometry = new THREE.SphereGeometry(5, 60, 40);
geometry.scale(-1, 1, 1);

const material = new THREE.MeshBasicMaterial({
  map: THREE.ImageUtils.loadTexture(testImage)
});

const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

// camera
const camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
camera.position.set(0, 0, 0.1);
camera.lookAt(sphere.position);

// helper
const axis = new THREE.AxesHelper(1000);
axis.position.set(0, 0, 0);
scene.add(axis);

// render
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0x000000);
document.getElementById("stage").appendChild(renderer.domElement);
renderer.render(scene, camera);

//control

const controls = new OrbitControls(camera, renderer.domElement);

function render() {
  requestAnimationFrame(render);
  sphere.rotation.y += (0.05 * Math.PI) / 180;
  renderer.render(scene, camera);
  controls.update();
}
render();

天球画像をグリグリ動かすことができました。