やりたいこと
当サイトではモジュールを用いたThreejsをベースに紹介していましたが、いまさらながら非モジュールのScriptとモジュールのScriptの差を確認します。
ThreejsのExmple/jsフォルダが削除され(著者の勘違いでなければ)、LoaderやExtentionがモジュールでないと使用できなりました。今後モジュール化することが必須に近いと思います。
環境
Threejs: r150
モジュールで動作させる準備
モジュールを読み込めるようにする
TypeがモジュールのJavaScriptを使用します。ローカルで使用する場合はChromeを特別な起動方法で起動する必要があります。通常のChromeはTypeがモジュールのJavaScriptを読み込むことができません。
Chromeを起動時に以下の引数を追加します。
--allow-file-access-from-files
Chromeのショートカットを作成してのリンク先の最後に上記の引数を追加するか、batを作成すると便利です。
上記方法でChromeを起動する際、すべてのChromeのWindowを閉じている必要があります。
非モジュールのコード
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas1" width=600 height=600></canvas>
<script src ="./js/libs/three.min.js"></script>
<script src ="./js/libs/3d.js"></script>
</body>
</html>
JavaScript
3d.js
let renderer;
let scene;
let camera;
scene = new THREE.Scene();
const canvas = document.querySelector("#canvas1");
renderer = new THREE.WebGLRenderer({ canvas: canvas });
const width = canvas.width;
const height = canvas.height;
renderer.setSize(width, height);
setupCamera();
setupObject(scene);
setupLights(scene);
function setupCamera() {
const canvas = document.querySelector("#canvas1");
const width = canvas.width;
const height = canvas.height;
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 3000);
camera.position.set(0, 10, 0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
function render() {
renderer.render(scene, camera);
}
function setupLights(scene) {
const light = new THREE.DirectionalLight(0xFFFFFF);
light.intensity = 1;
light.position.set(10, 20, -20);
scene.add(light);
}
function setupObject(scene) {
const geometry = new THREE.SphereGeometry(2, 32, 32);
const material = new THREE.MeshStandardMaterial({ color: 0xffff00 });
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
requestAnimationFrame(render);
}
モジュールのコード
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas1" width=600 height=600></canvas>
<script type="importmap">{"imports": {"three": "./js/libs/three.module.js"}}</script>
<script type="module" src="./js/libs/3d.js"></script>
</body>
</html>
JavaScript
3d.js
import * as THREE from 'three';
let renderer;
let scene;
let camera;
scene = new THREE.Scene();
const canvas = document.querySelector("#canvas1");
renderer = new THREE.WebGLRenderer({ canvas: canvas });
const width = canvas.width;
const height = canvas.height;
renderer.setSize(width, height);
setupCamera();
setupObject(scene);
setupLights(scene);
function setupCamera() {
const canvas = document.querySelector("#canvas1");
const width = canvas.width;
const height = canvas.height;
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 3000);
camera.position.set(0, 10, 0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
function render() {
renderer.render(scene, camera);
}
function setupLights(scene) {
const light = new THREE.DirectionalLight(0xFFFFFF);
light.intensity = 1;
light.position.set(10, 20, -20);
scene.add(light);
}
function setupObject(scene) {
const geometry = new THREE.SphereGeometry(2, 32, 32);
const material = new THREE.MeshStandardMaterial({ color: 0xffff00 });
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
requestAnimationFrame(render);
}
相違点
HTML
非モジュール
<script src ="./js/libs/three.min.js"></script>
<script src ="./js/libs/3d.js"></script>
モジュール
<script type="importmap">{"imports": {"three": "./js/libs/three.module.js"}}</script>
<script type="module" src="./js/libs/3d.js"></script>
非モジュールではthree.min.js(もしくはthree.js)をhtmlで読み込みます。
モジュールではimportmapを指定する必要があります。(上記の1行目)”./js/libs/three.module.js”は環境ごとに変更します。
作成するJavascriptのTypeに”module”を設定します。
JavaScript
モジュールでは以下の1行が必要です。
import * as THREE from 'three';
ほかに差異はありません。
この例ではThreejsのクラスをネームスペースTHREEで読み込んでいるため、Import以外の修正が不要ですが、import の書き方によりネームスペースの変更が必要になります。
結果
上記の例ではモジュール/非モジュールともに黄色の球が表示されます。
コメント