[Three.js] PlaneのサイズをDOM上のサイズと合わせる

前回の続き。

PlaneGeometryのサイズをHTMLのオブジェクトと同じサイズにする。

HTMLは以下の構造。

	<div class="card card01">
		<img src="./images/texture01.jpg" alt="">
	</div>

	<div class="card card02">
		<img src="./images/texture02.jpg" alt="">
	</div>

	<div class="card card03">
		<img src="./images/texture03.jpg" alt="">
	</div>
import * as THREE from "three";

import { PhotoPlane } from "./Mesh/PhotoPlane";


(function(window, document) {

	class Common {

		/**
		 * メイン
		 * @constructor
		 */
		constructor() {

			this.scene = null;
			this.camera = null;
			this.renderer = null;

			this.planes = [];

			this.init();

		}



		/**
		 * 初期化
		 */
		init = () => {

			this.ww = window.innerWidth;
			this.wh = window.innerHeight;

			// シーンの生成
			this.scene = new THREE.Scene();

			// カメラ
			this.camera = new THREE.OrthographicCamera(this.ww / -2, this.ww / 2, this.wh / 2, this.wh / -2, 1, 10);
			this.camera.position.z = 1;

			// レンダラーの生成と追加(要するにcanvas要素である)
			this.renderer = new THREE.WebGLRenderer();
			this.renderer.setSize(this.ww, this.wh);
			document.body.appendChild( this.renderer.domElement );

			let cards = document.querySelectorAll('.card');

			cards.forEach((el) => {

				const plane = new PhotoPlane(el);
				this.scene.add(plane);
				this.planes.push(plane);

			});

			this.animate();

		}


		animate = () => {

			requestAnimationFrame( this.animate );

			this.renderer.render( this.scene, this.camera );

		}

	}




	new Common();

})(window, document);
export class PhotoPlane extends THREE.Mesh {

	/**
	 *
	 * @constructor
	 */
	constructor(el) {

		const img = el.querySelector('img');

		const rect = el.getBoundingClientRect()
		const {
			left,
			top,
			width,
			height
		} = rect;

		const geometry = new THREE.PlaneGeometry(width, height);

		const loader = new THREE.TextureLoader();
		const texture = loader.load(img.src);

		const material = new THREE.MeshBasicMaterial( { map:texture } );

		super(geometry, material);

		const pos = {
			x: (left + (width / 2)) - (window.innerWidth / 2),
			y: (window.innerHeight / 2) - (top + (height / 2))
		}

		this.position.x = pos.x
		this.position.y = pos.y

	}

}

前回同様Three.Meshを継承したPhotoPlaneクラスでは、渡されたElementのサイズなどをgetBoundingClientRectで取得して位置、サイズを適用しています。

重要なのは、THREE.OrthographicCameraをカメラとして利用しているところで、このカメラは遠近感によるサイズの変化がなくなるので注意。

デモはこちら。