Angular, Beyond the DOM

by Austin McDaniel

About ME...

Austin McDaniel

Github: @amcdnl

Twitter: @amcdnl

#ngPanda

We've came

so FAR....

in our journey with

computers...

and the way we

interact...

with them and the

interfaces...

AngularJS helped us climb                      

with the web...

mountains

Virtual Reality is the

next evolution...

VR is actually          

tricks turned new...

OLD

                    for VR...

Evolving

Same Problems,

  • Interaction Events: Click, Keyboard, Touch
  • View port Events: Window resize
  • Life cycle hooks: init, render, destroy
  • Animations
  • Dataflow

different story

And more

  • Desktop / Mobile VR
  • Head Tracking
  • Gestures
  • Voice Recognition for Input
  • Shaders

challenges

var camera = new THREE.PerspectiveCamera(
  20, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1800;

var scene = new THREE.Scene();

var light = new THREE.DirectionalLight(0xffffff);
var light.position.set(0, 0, 1);
scene.add(light);

document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);

function onWindowResize() {
  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  camera.position.x += (mouseX - camera.position.x) * 0.05;
  camera.position.y += (-mouseY - camera.position.y) * 0.05;
  camera.lookAt(scene.position);
  renderer.render(scene, camera);
}

There is

<a-scene>
  <a-light type="ambient" color="#222">
  </a-light>
  <a-sphere id="mouth"
    color="#000"
    position="0 1 -4"
    shader="flat">
   </a-sphere>
</a-scene>

hope

Wait, is that Angular?

What if it could be?

  • Web
  • Mobile Native
  • Desktop Native
  • Server-side

Custom renderers!

Override the

default DOM Renderer...

Angular                     Markup

<ngx-renderer>
  <ngx-orbit-controls></ngx-orbit-controls>
  <ngx-scene>
    <ngx-perspective-camera></ngx-perspective-camera>
    <ngx-point-light></ngx-point-light>
    <ngx-sphere
      *ngFor="let ball of balls"
      [positionY]="ball * 5"
      [positionX]="ball * 5"
      [positionZ]="0">
    </ngx-sphere>
  </ngx-scene>
</ngx-renderer>

WebGL

Under the hood...

@Component({
  selector: 'ngx-sphere',
  template: `<ng-content></ng-content>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SphereComponent implements OnInit {

  ngOnInit(): void {
    const geometry = new SphereGeometry(3, 50, 50, 0, Math.PI * 2, 0, Math.PI * 2);
    const material = new MeshNormalMaterial();
    const sphere = new Mesh(geometry, material);

    sphere.position.y = this.positionY;
    sphere.position.x = this.positionX;
    sphere.position.z = this.positionZ;
  }

}

Inside the engine...

@Component({
  selector: 'ngx-scene',
  template: `<ng-content></ng-content>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SceneComponent implements AfterContentInit {

  @ContentChildren(SphereComponent)
  sphereComps: any;

  ngAfterContentInit(): void {
    for(const mesh of this.sphereComps.toArray()) {
      this.scene.add(mesh.object);
    }
  }

}

Apply the stereoscopic filters

Polyfills required

Demo!

  • Better Render Perf

  • Native Compilation?

Whats next?