ICS MEDIA - インタラクションデザイン×ウェブテクノロジー

WebGL と JavaScript で学ぶ3D表現

Three.jsのスクリーン座標の算出

Three.jsのcanvas要素にHTMLの表示を重ねたい時があります。

そのときに必要となるのが、canvas要素上のオブジェクトの座標です。これは、描写面であるcanvas要素上の座標のことなので、スクリーン座標と言います。

スクリーン座標の算出方法

THREE.Cameraクラスのproject()メソッドを使うことで、ワールド座標をステージ上のXY座標に変換することができます。

const project = object3D.project(camera);

project()メソッドの戻り値はTHREE.Vector3D型で、xyはそれぞれ-1.0+1.0の値をとります。zは3Dオブジェクトの深度を示します。

2D座標の取得には、rendererインスタンスの幅・高さの値を計算することでcanvas要素の左上からの座標を求めることができます。

const object3D = new Mesh(); // 任意の3Dオブジェクト
const width = 960; // rendererのサイズ
const height = 540;

// スクリーン座標を取得する
const project = object3D.position.project(camera);
const sx = width / 2 * (+project.x + 1.0);
const sy = height / 2 * (-project.y + 1.0);

// スクリーン座標
console.log(sx, sy);

スクリーン座標算出のサンプル

次のサンプルは球体が3D空間内を円周上を移動している様子を表現したものですが、球体のスクリーン座標をテキストで表示するようにしています。

このサンプルではcanvasに重ねて任意のdiv要素を重ね合わせます。座標の原点をあわせておきたいので、CSSのposition:absoluteで2つの要素の絶対座標をリセットしておきます。親のdiv要素の原点を基点としたいのでposition:relativeを指定します。

<!-- 親のタグの基準点をリセット -->
<div style="position:relative;">
  <!-- Three.js用のcanvasタグ -->
  <canvas style="position: absolute; top: 0; left: 0;"></canvas>

  <!-- 座標表示用のdivタグ -->
  <div style="position: absolute; top: 0; left: 0;"></div>
</div>