見出し画像

Three.js第2弾!アニメーションを加えてみた【初心者向け】 

こんにちは!ALCHEMYのエンジニア、丸山です。
前回の記事でオブジェクトを作成しましたので、今回は簡単なアニメーションを加えてみようと思います。
アニメーションを加える方法を学ぶと、出来ることの幅が広がるので、3Dでのモノ作りがより一層楽しくなります!
Three.js 初心者の方にも分かりやすい説明をするように心がけるので、ぜひ参考にしてみてください。記事の最後にソースコードを載せています!

今回の記事でやりたいこと:
下記画像のように作成したオブジェクトにアニメーションを追加

アニメーションが追加されたオブジェクト

1. アニメーションの原理

Three.js はストップモーションのようにフレーム毎にオブジェクトの位置を変えて画面に表示(レンダリング)させています。そうすることで、人間の目にはオブジェクトがアニメーションのように滑らかに動いて見えます。
モニター環境にもよりますが、1秒間に平均60フレーム(60fpsの場合)表示させています。1フレームあたり約16.67ミリ秒間、画面上に表示されている計算になります。
各フレーム毎にオブジェクトの位置を少しずつ変えることによって、アニメーションを実現することができます。

今回はwindow.requestAnimationFrame(...)というメソッドを使用します。

2. window.requestAnimationFrame(...)とは

window.requestAnimationFrame(...)は、引数として渡した関数を次のフレーム(約16.67ミリ秒後に表示されるフレーム)で実行してくれます。この原理を利用することによって、ループを作成することができます。
以下のようにコードを追加しましょう。

import * as THREE from "three";

const canvas = document.querySelector("canvas.webgl");

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const sizes = {
  width: 800,
  height: 600,
};

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 5;
scene.add(camera);

const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});


***********追加したコード************

const tick = () => {
  console.log('次のフレーム')

  window.requestAnimationFrame(tick)
};

tick();
***********************************


renderer.setSize(sizes.width, sizes.height);
renderer.render(scene, camera);


コンソールを確認していただくと、以下のように数字が増加していると思います。

window.requestAnimationFrame(...)にtick 関数を渡すことによって、フレーム毎にtick関数が永久に呼ばれるようになりました。

それでは、オブジェクトをy軸に沿って回転させるためtick関数に下記を追加します。

mesh.rotation.y += 0.01

そして、フレーム毎にレンダリング(画面に表示)をさせる必要があるので、下記をtick関数内に移動します。

renderer.render(scene, camera)

そうすると下記のように、オブジェクトが回転しているはずです。

いかがでしたか?こんなに簡単にアニメーションが作成できます!
アニメーションを加えるやり方は他にもありますので、興味のある方はぜひ調べてみてください。
最後までお読みいただき、ありがとうございました。

ソースコード

import * as THREE from "three";
import gsap from "gsap";

const canvas = document.querySelector("canvas.webgl");

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const sizes = {
  width: 800,
  height: 600,
};

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 5;
scene.add(camera);

const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
});


  // ***********追加したコード************
const tick = () => {

  mesh.rotation.y += 0.01;

  renderer.render(scene, camera);

  window.requestAnimationFrame(tick);
};
  // ***********************************


tick();
renderer.setSize(sizes.width, sizes.height);
renderer.render(scene, camera);


株式会社ALCHEMYでは、一緒に働く仲間を募集しています。