javascript AngularJS 绑定到 WebGL/Canvas

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16054424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:05:17  来源:igfitidea点击:

AngularJS Binding to WebGL / Canvas

javascriptmodel-view-controllercanvasangularjswebgl

提问by SpaceCowboy2071

I'm very green to AngularJS. I'm wondering if it's possible to use it when your view is using HTML5 Canvas or WebGL? If so, are there any good tutorials on how you go about this?

我对 AngularJS 非常友好。我想知道当您的视图使用 HTML5 Canvas 或 WebGL 时是否可以使用它?如果是这样,是否有任何关于如何进行此操作的好的教程?

I've seen several games boast they are made using AngularJS, but I don't know if that is limited to their menus, leaderboards, and other dashboard elements.

我见过一些游戏吹嘘它们是使用 AngularJS 制作的,但我不知道这是否仅限于它们的菜单、排行榜和其他仪表板元素。

(I wouldn't necessarily be using MVC in a game, but obviously you can do more than just games with Canvas and WebGL.)

(我不一定会在游戏中使用 MVC,但显然你可以做的不仅仅是使用 Canvas 和 WebGL 的游戏。)

Thanks!

谢谢!

回答by winkerVSbecks

EDIT: I made a full example of a WebGL directive using three.js with bindings to resize the object or change it's material type. Also, events such as window resizing and mouse moved:

编辑:我使用带有绑定的three.js制作了一个WebGL指令的完整示例,以调整对象大小或更改其材质类型。此外,诸如窗口大小调整和鼠标移动之类的事件:



Yes this is very much possible. Beyond the menus, leaderboards, etc. you can wrap your canvasinto a directive too.

是的,这很有可能。除了菜单、排行榜等,您也可以将您的内容包装canvas到指令中。

  1. The controller will setup the game state
  2. Pass this state, loaded data from server and any other data you might have to the directive
  3. Finally you init the canvas in the directives link function
  1. 控制器将设置游戏状态
  2. 将此状态、从服务器加载的数据以及您可能拥有的任何其他数据传递给指令
  3. 最后在指令链接函数中初始化画布

I made this little app to help me with a school project: http://callmethey.herokuapp.com/polygons. This is the directive I use (with three.js for the canvas part):

我制作了这个小应用程序来帮助我完成一个学校项目: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
  };
});

回答by cubicleDowns

Another technique is to encapsulate the WebGL scene as a factory and expose access to the 3D scene to the module via the returned factory API. One advantage of this approach is that you can inject the scene into any other Controller or Directive. Factories in Angular are singletons so there is only 1 copy of the 3D scene floating around.

另一种技术是将 WebGL 场景封装为工厂,并通过返回的工厂 API 向模块公开对 3D 场景的访问。这种方法的一个优点是您可以将场景注入任何其他控制器或指令。Angular 中的工厂是单例的,所以只有 1 个 3D 场景的副本四处浮动。

This encapsulation method also allows you to isolate both the 3D scene-logic from your application-logic.

这种封装方法还允许您将 3D 场景逻辑与应用程序逻辑隔离。

You should be able to use MOST pre-existing WebGL code as long as you init the factory via the exposed Factory API. To do this, copy all your 3D scene code into a factory and then call an init function of the injected 3D factory from your controller to initialize rendering.

只要您通过公开的 Factory API 初始化工厂,您就应该能够使用 MOST 预先存在的 WebGL 代码。为此,请将所有 3D 场景代码复制到工厂中,然后从控制器调用注入的 3D 工厂的 init 函数以初始化渲染。

I used directives to on the canvas element to define the scene interaction. Click, marquee, keypress, events.

我在画布元素上使用指令来定义场景交互。单击、选取框、按键、事件。

Angular and Three.js architecture demo

Angular 和 Three.js 架构演示