web-dev-qa-db-ja.com

WebGL / CanvasへのAngularJSバインディング

私はAngularJSに対して非常に環境に配慮しています。ビューでHTML5 CanvasまたはWebGLを使用しているときにそれを使用できるかどうか疑問に思っていますか?もしそうなら、これをどのように進めるかについての良いチュートリアルはありますか?

AngularJSを使用して作成された自慢のゲームをいくつか見ましたが、それがメニュー、リーダーボード、およびその他のダッシュボード要素に限定されているかどうかはわかりません。

(私は必ずしもゲームでMVCを使用しているわけではありませんが、CanvasとWebGLを使用してゲーム以上のことができることは明らかです。

ありがとう!

24
SpaceCowboy2071

編集:オブジェクトのサイズを変更したり、オブジェクトのマテリアルタイプを変更したりするために、バインディングを使用してthree.jsを使用するWebGLディレクティブの完全な例を作成しました。また、ウィンドウのサイズ変更やマウスの移動などのイベントは次のとおりです。


はい、これは非常に可能です。メニューやリーダーボードなどの他に、canvasをディレクティブにラップすることもできます。

  1. コントローラはゲームの状態を設定します
  2. この状態、サーバーからロードされたデータ、およびその他の必要なデータをディレクティブに渡します
  3. 最後に、ディレクティブリンク関数でキャンバスを初期化します

私は学校のプロジェクトを支援するためにこの小さなアプリを作成しました: http://callmethey.herokuapp.com/polygons 。これは私が使用するディレクティブです(キャンバス部分にthree.jsを使用):

app.directive('polygon', function() {
  return {
    restrict: 'A',
    scope: { 
      vertices: '=polygon',  
      color: '=color'
    },
    link: function(scope, element, attrs)
    {
      var camera, scene, renderer;
      var polygon;
      var targetRotation = 0;
      var targetYRotation = 0, targetXRotation = 0;
      var targetYRotationOnMouseDown = 0, targetXRotationOnMouseDown = 0;
      var mouseX = 0, mouseY = 0;
      var mouseXOnMouseDown = 0, mouseYOnMouseDown = 0;
      var width = $(element).width();
      var height = 200;
      var widthHalfX = width/2;
      var widthHalfY = height/2;

      init();

      function init() {
        // Setup scene
        camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 300;
        scene = new THREE.Scene();
        // Build Polygon
        var geometry =  new THREE.Geometry();
        angular.forEach(scope.vertices, function (v) {
          geometry.vertices.Push( new THREE.Vector3( v.x, v.y, v.z ) );
        });
        geometry.faces.Push( new THREE.Face3(0, 1, 2 ));
        THREE.GeometryUtils.center( geometry );
        // Push polygon to scene
        var material = new THREE.MeshBasicMaterial( { color: cols[scope.color], side: THREE.DoubleSide } );
        polygon = new THREE.Mesh( geometry, material );
        scene.add(polygon);
        renderer = new THREE.WebGLRenderer();
        renderer.setSize( width, height );
      }

     // ..... rest of the code truncated for readability
  };
});
27
winkerVSbecks

もう1つの手法は、WebGLシーンをファクトリとしてカプセル化し、返されたファクトリAPIを介して3Dシーンへのアクセスをモジュールに公開することです。このアプローチの利点の1つは、シーンを他のコントローラーまたはディレクティブに挿入できることです。 Angularのファクトリはシングルトンであるため、3Dシーンのコピーは1つしかありません。

このカプセル化方法では、3Dシーンロジックをアプリケーションロジックから分離することもできます。

公開されたファクトリAPIを介してファクトリを初期化する限り、既存のWebGLコードを使用できるはずです。これを行うには、すべての3Dシーンコードをファクトリーにコピーし、注入された3Dファクトリーのinit関数をコントローラーから呼び出してレンダリングを初期化します。

シーンの相互作用を定義するために、canvas要素でにディレクティブを使用しました。クリック、マーキー、キー押下、イベント。

Angular and Three.js architecture demo

9
cubicleDowns