見出し画像

【Three.js】サンプルコードをモダンな書き方に直す

Three.js のチュートリアルをいろいろ探していたら「Three.jsの基礎知識」という素晴らしいサイトを見つけました。

元々は「Three.js Fundamentals」という英語のサイトですが、有志の方々によって日本語を含む様々な言語に翻訳されています。ありがたいですね。

<script src="path/to/three.js"></script> という書き方は古いらしい

チュートリアルの最初のページに

バージョンr106以降でthree.jsを使用する好ましい方法は es6モジュールです。

と書かれています。また、原文の方には

If you'd prefer the old <script src="path/to/three.js"></script> style you can check out an older version of this site.

と書かれています。(日本語訳がちょっと読みにくい文章だったので原文の方を参照しています。)
要するに、<script src="path/to/three.js"></script> という書き方は古いらしいです。

Three.js のポリシーとして後方互換性を気にしなくて良い作りにしているらしく、どちらの書き方でも動作するようですが、折角なのでモダンな書き方に直してみたいと思います。(まだどんなメリットがあるのか分かっていない)

元のコードはこちらです。

1. fuga_1.html

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8"/>
   <script type="module">
       import * as THREE from "https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.module.min.js";
       // ページの読み込みを待つ
       window.addEventListener('load', init);

       function init() {

           // サイズを指定
           const width = 960;
           const height = 540;

           // レンダラーを作成
           const renderer = new THREE.WebGLRenderer({
               canvas: document.querySelector('#myCanvas')
           });
           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);
           }
       }
   </script>
</head>
<body>
   <canvas id="myCanvas"></canvas>
</body>
</html>

変更点としては
・script タグが1つになり、type="module" を指定
・Three.js の読み込み方を import に変更
・読み込む Three.js を three.min.js から three.module.min.js に変更
です。import の行以降は全く変更していません。

こちらのサンプルはローカルでファイルを開いても動作します。

2. fuga_2.html と piyo.js

fuga_2.html

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8"/>
   <script type="module" src="piyo.js"></script>
</head>
<body>
   <canvas id="myCanvas"></canvas>
</body>
</html>

変更点としては
・Three.js の読み込み用の script タグを削除
・piyo.js の読み込み用の script タグで type="module" を指定
です。
(piyo.js を読み込むのに script タグを使っている部分は他のやり方があるのかも知れません)

piyo.js

import * as THREE from "https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.module.min.js";
// ページの読み込みを待つ
window.addEventListener('load', init);

function init() {

   // サイズを指定
   const width = 960;
   const height = 540;

   // レンダラーを作成
   const renderer = new THREE.WebGLRenderer({
       canvas: document.querySelector('#myCanvas')
   });
   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);
   }
}

変更点としては
・1行目に import を追加し、読み込む Three.js を three.min.js から three.module.min.js に変更
です。

こちらのサンプルは今回の変更によりローカルからは実行できなくなりました。
Web サーバーを立てて動かして下さい。

簡単な Web サーバーの立て方はこちらを参照して下さい。


この記事が気に入ったらサポートをしてみませんか?