概要

今回は表示した物体をアニメーションさせてみる。

@CretedDate 2013/08/19
@Versions Three.js r59

回してみる

まずは簡単なところで、rotationをフレームごとに変えることで、物体をぐるぐる回してみる。

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'> 
  <script src="three.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
  <script>
    var APP = { };

    APP.animate = function() {
      APP.cube.rotation.x = APP.cube.rotation.x + 0.01;
      APP.cube.rotation.y = APP.cube.rotation.y + 0.01;
      APP.renderer.render(APP.scene, APP.camera);
      window.requestAnimationFrame( APP.animate );
    }

    $(document).ready( function() {
      // Rendererを用意
      APP.renderer = new THREE.WebGLRenderer( { 'canvas' : $('#canvas')[0] } );
      APP.renderer.setSize(300, 300);

      // Cameraを用意
      APP.camera = new THREE.PerspectiveCamera();
      APP.camera.position.z = 500;

      // Sceneを用意
      APP.scene = new THREE.Scene();
      APP.scene.add( APP.camera );

      // 球を作る
      var sphere = new THREE.CubeGeometry(100, 100, 100);
      var material = new THREE.MeshLambertMaterial( { color: 0x33ccff } )
      APP.cube = new THREE.Mesh( sphere, material );
      APP.scene.add( APP.cube );

      // 光
      var light = new THREE.SpotLight(0xffffff);
      light.position.set( 0, 500, 500 );
      APP.scene.add( light );

      APP.animate();
    } );
  </script>
</head>

<body>
  <canvas id="canvas" style="border:solid 1px; margin: 30px;">
    青春キャンパス
  </canvas>
</body>

</html>

青いCubeを書いて、そこにSpotLightを当ててます。あとはanimate関数でフレームごとにrotationを変動させる処理を書いています。

このソースの動作は下記リンク参照。

examples/animation_rotate.html

左右に動かしてみる

X軸のpositionを変更することで、左右に動かしてみる。

    APP.moveX = 2;
    APP. animate = function() {
      // 150で方向転換
      if( Math.abs( APP.cube.position.x ) > 150 ) APP.moveX *= -1;
      // X軸に移動
      APP.cube.position.x += APP.moveX;
      // なんとなく回転もさせておく
      APP.cube.rotation.x += 0.01;
      APP.cube.rotation.y += 0.01;

      APP.renderer.render(APP.scene, APP.camera);
      window.requestAnimationFrame( APP.animate );
    }

position.xを適当に増減させてるだけですね。これを実行すると、下記リンクのような動きになります。

examples/animation_movex.html

X軸とY軸を動かしてみる

上の例ではX軸しか動かしてなかったので、Y軸も動かしてみる。

    APP.moveX = 2;
    APP.moveY = 2;
    APP. animate = function() {
      // 150で方向転換(角度は少しランダム・徐々にスピードアップ)
      if( Math.abs( APP.cube.position.x ) > 150 ) {
        APP.moveX = Math.abs( APP.moveX ) + (Math.random() / 5 - 0.05);
        if( APP.cube.position.x > 150 ) APP.moveX *= -1;
      }
      if( Math.abs( APP.cube.position.y ) > 150 ) {
        APP.moveY = Math.abs( APP.moveY ) + (Math.random() / 5 - 0.05);
        if( APP.cube.position.y > 150 ) APP.moveY *= -1;
      }
      // 移動
      APP.cube.position.x += APP.moveX;
      APP.cube.position.y += APP.moveY;
      // なんとなく回転もさせておく
      APP.cube.rotation.x += 0.01;
      APP.cube.rotation.y += 0.01;

      APP.renderer.render(APP.scene, APP.camera);
      window.requestAnimationFrame( APP.animate );
    }

同じ方向に跳ね返ってもつまらないので、速度にランダム要素を加えている。ランダムの期待値が若干プラスになるようにしているので、徐々にスピードアップします。放っておくとものすごいスピードで動きます。-0.05のところを-0.1にすれば、だいたい同じような速度で動くはず。

examples/animation_movexy.html

カメラを動かしてみる

物体ではなくカメラを動かしてみる。まずは簡単に、徐々にカメラが近づけてみる。

    var APP = { };

    APP. animate = function() {
      if( APP.camera.position.z < 0 ) APP.camera.position.z = 500;
      APP.camera.position.z -= 1;

      APP.renderer.render(APP.scene, APP.camera);
      window.requestAnimationFrame( APP.animate );
    }

    $(document).ready( function() {
      // Rendererを用意
      APP.renderer = new THREE.WebGLRenderer( { 'canvas' : $('#canvas')[0] } );
      APP.renderer.setSize(300, 300);

      // Cameraを用意
      APP.camera = new THREE.PerspectiveCamera();
      APP.camera.position.z = 500;

      // Sceneを用意
      APP.scene = new THREE.Scene();
      APP.scene.add( APP.camera );

      // 球を作る
      for( var i = 0; i < 100; i++ ) {
        var geometry = new THREE.SphereGeometry(10);
        var material = new THREE.MeshLambertMaterial( { color: 0xffffff } )
        var mesh = new THREE.Mesh( geometry, material ); 
        mesh.position.set( Math.random()*500-250, Math.random()*500-250, Math.random()*500-250 );
        APP.scene.add( mesh );
      }

      // 光
      var light = new THREE.SpotLight(0xffffff);
      light.position.set( 0, 500, 500 );
      APP.scene.add( light );

      APP.animate();
    } );

カメラのpositionを1ずつ近づけている。

examples/animation_camera1.html

ただ近づけるだけでは面白みがないので、周囲を回してみる。

    APP.pos = 0;
    APP. animate = function() {
      APP.pos += 0.01;
      APP.camera.position.x = Math.cos( APP.pos ) * 500;
      APP.camera.position.z = Math.sin( APP.pos ) * 500;
      APP.camera.lookAt(new THREE.Vector3(0,0,0));

      APP.renderer.render(APP.scene, APP.camera);
      window.requestAnimationFrame( APP.animate );
    }

カメラのポジションを500の距離で円運動させつつ、視点の向き先を0,0,0のポジションに合わせている。

examples/animation_camera2.html

マウスでカメラを動かす

マウスのドラッグやホイールでカメラを動かすこともできる。自前でやるのは面倒なので、three.jsのExamplesに用意されているcontrolsの子を使う。

下記はTrackballControls.jsを使った場合の例。

  <script src="three.js"></script>
  <script src="TrackballControls.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
  <script>
    var APP = { };

    APP.animate = function() {
      APP.renderer.render( APP.scene, APP.camera );
      APP.controls.update();
      requestAnimationFrame( APP.animate );
    };

    $(document).ready( function() {
      // Rendererを用意
      APP.renderer = new THREE.WebGLRenderer( { 'canvas' : $('#canvas')[0] } );
      APP.renderer.setSize(300, 300);

      // Cameraを用意
      APP.camera = new THREE.PerspectiveCamera();
      APP.camera.position.z = 500;

      // Sceneを用意
      APP.scene = new THREE.Scene();
      APP.scene.add( APP.camera );

      // 球を作る
      for( var i = 0; i < 100; i++ ) {
        var geometry = new THREE.SphereGeometry(10);
        var material = new THREE.MeshLambertMaterial( { color: 0xaaffff } )
        var mesh = new THREE.Mesh( geometry, material ); 
        mesh.position.set( Math.random()*500-250, Math.random()*500-250, Math.random()*500-250 );
        APP.scene.add( mesh );
      }

      // 光源を用意
      var light = new THREE.DirectionalLight(0xffffff);
      light.position.set(1, 1, 1).normalize();
      APP.scene.add( light );

      // Controlsを用意
      APP.controls = new THREE.TrackballControls( APP.camera );

      APP.animate();
    } );
  </script>

animate functionのところで、controlsをupdateする記述を入れています。これで定義しておいたTrackballControlsを利用することができます。実際の動きは下記リンク参照。マウスのドラッグで回転、ホイールでズームします。

examples/animation_trackball.html