Sr Engineer @nrwl
Core team member @nestframework
Brand new father
Creator of @automapper/core
This is not a "how to". This presentation is to show an introduction to and what the library is leveraging (from Angular) to make everything work. So I hope everybody learns something from today's presentation.
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)
const mesh = new THREE.Mesh()
mesh.geometry = new THREE.BoxGeometry()
mesh.material = new THREE.MeshPhongMaterial()
scene.add(mesh)
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshPhongMaterial()
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
with Angular 3
with Angular 3
with Angular 3 THREE (.js)
@Component({
selector: 'app-root',
template: `
<ngt-canvas>
<ngt-mesh
o3d
(animateReady)="onAnimateReady($event.animateObject)"
>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
`
})
export class AppComponent {
onAnimateReady(cube: THREE.Mesh) {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
}
}
and of course...the imports
import { ThreeCoreModule } from '@angular-three/core';
import { ThreeMeshModule } from '@angular-three/core/meshes';
import { ThreeBoxBufferGeometryModule } from '@angular-three/core/geometries';
import { ThreeMeshBasicMaterialModule } from '@angular-three/core/materials';
@NgModule({
imports: [
/* ... */,
ThreeCoreModule,
ThreeMeshModule,
ThreeBoxBufferGeometryModule,
ThreeMeshBasicMaterialModule
]
})
export class AppModule {}
@Component({
selector: 'app-root',
template: `
<ngt-canvas>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
`
})
export class AppComponent {}
<ngt-canvas>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
<ngt-canvas>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
<ngt-canvas>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
<ngt-canvas>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
</ngt-canvas>
<parent>
<child></child>
</parent>
<parent>
<child></child>
</parent>
<parent>
<!-- aka the content -->
<child></child>
</parent>
<parent>
<child></child>
</parent>
<parent>
<!-- aka the content -->
<child></child>
</parent>
@Component({
selector: 'parent',
template: `
<ng-content></ng-content>
`
})
export class ParentComponent {
@ContentChild(ChildComponent) childComp: ChildComponent;
}
<parent>
<child></child>
</parent>
<parent>
<!-- aka the content -->
<child></child>
</parent>
@Component({
selector: 'parent',
template: `
<ng-content></ng-content>
`
})
export class ParentComponent {
@ContentChild(ChildComponent) childComp: ChildComponent;
}
<parent>
<child></child>
</parent>
<parent>
<!-- aka the content -->
<child></child>
</parent>
@Component({
selector: 'parent',
template: `
<!-- nothing to see here -->
`
})
export class ParentComponent {
@ContentChild(ChildComponent) childComp: ChildComponent;
}
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
}
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
}
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
private mesh?: THREE.Mesh;
ngOnInit() {
this.mesh = new THREE.Mesh(
this.geometryDirective.geometry,
this.materialDirective.material
);
}
}
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
private mesh?: THREE.Mesh;
ngOnInit() {
this.mesh = new THREE.Mesh(
this.geometryDirective.geometry,
this.materialDirective.material
);
}
}
<ngt-mesh>
<ngt-box-geometry></ngt-box-geometry>
<ngt-mesh-basic-material></ngt-mesh-basic-material>
</ngt-mesh>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
private mesh?: THREE.Mesh;
ngOnInit() {
this.mesh = new THREE.Mesh(
this.geometryDirective.geometry,
this.materialDirective.material
);
}
}
@Component({
selector: 'ngt-canvas',
template: `<canvas #renderCanvas></canvas>`,
providers: [
CanvasStore,
AnimationStore,
EventsStore,
LoopService,
/* some other injectables */
]
})
export class CanvasComponent {}
@Component({
selector: 'ngt-canvas',
template: `<canvas #renderCanvas></canvas>`,
providers: [
CanvasStore,
AnimationStore,
EventsStore,
LoopService,
/* some other injectables */
]
})
export class CanvasComponent {}
// Remember?
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)
// setup Mesh
scene.add(mesh)
// Remember?
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)
// setup Mesh
scene.add(mesh)
CanvasComponent sets up:
scene.add(mesh)
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Component({
/* ... */
})
export class CanvasComponent {
@ContentChild(MeshDirective) meshDirective: MeshDirective;
}
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Component({
/* ... */
})
export class CanvasComponent {
@ContentChild(MeshDirective) meshDirective: MeshDirective;
}
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Component({
/* ... */,
providers: [
CanvasStore, // <-- this store initializes a THREE.Scene
/* .. */
]
})
export class CanvasComponent {
@ContentChild(MeshDirective) meshDirective: MeshDirective;
}
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Component({
/* ... */,
providers: [
CanvasStore, // <-- this store initializes a THREE.Scene
/* .. */
]
})
export class CanvasComponent {
@ContentChild(MeshDirective) meshDirective: MeshDirective;
/**
* this.canvasStore.scene.add(this.meshDirective.mesh);
* /
}
scene.add(mesh)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Component({
/* ... */,
providers: [
CanvasStore, // <-- this store initializes a THREE.Scene
/* .. */
]
})
export class CanvasComponent {
@ContentChild(MeshDirective) meshDirective: MeshDirective;
/**
* this.canvasStore.scene.add(this.meshDirective.mesh);
* /
}
scene.add(mesh)
scene.add(literally_any_THREE_object)
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
<ngt-anything></ngt-anything>
<ngt-anything-2></ngt-anything-2>
</ngt-canvas>
@Component({
/* ... */,
providers: [
CanvasStore,
/* .. */
]
})
export class CanvasComponent {
// WHAT ELSE DO WE NEED TO QUERY FOR???? NOBODY KNOWS
@ContentChild(MeshDirective) meshDirective: MeshDirective;
}
<parent>
<child></child>
</parent>
<parent>
<child></child>
</parent>
@Component({
selector: 'child',
template: ``
})
export class ChildComponent {
}
<parent>
<child></child>
</parent>
@Component({
selector: 'child',
template: ``
})
export class ChildComponent {
constructor(private readonly parentComponent: ParentComponent) {}
}
<parent>
<child></child>
</parent>
@Component({
selector: 'child',
template: ``
})
export class ChildComponent {
constructor(private readonly parentComponent: ParentComponent) {}
}
// Remember:
@Component({
providers: [/* ... */]
})
export class ParentComponent
<parent>
<child></child>
</parent>
@Component({
selector: 'child',
template: ``
})
export class ChildComponent {
constructor(
private readonly parentComponent: ParentComponent,
/* any provider on the parent injector is available here */
) {}
}
<parent>
<child></child>
</parent>
@Component({
selector: 'child',
template: ``
})
export class ChildComponent {
constructor(
private readonly parentComponent: ParentComponent,
/* any provider on the parent injector is available here */
) {}
}
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
ngOnInit() {
this.mesh = new THREE.Mesh(/* ... */);
}
}
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
constructor(private readonly canvasStore: CanvasStore) {}
ngOnInit() {
this.mesh = new THREE.Mesh(/* ... */);
this.canvasStore.scene.add(this.mesh);
}
}
<ngt-canvas>
<ngt-mesh>
<!-- stuffs -->
</ngt-mesh>
</ngt-canvas>
@Directive({
selector: 'ngt-mesh'
})
export class MeshDirective {
constructor(private readonly canvasStore: CanvasStore) {}
ngOnInit() {
this.mesh = new THREE.Mesh(/* ... */);
this.canvasStore.scene.add(this.mesh);
}
}
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
@ContentChild(ThreeGeometry) geometryDirective?: ThreeGeometry;
@ContentChild(ThreeMaterial) materialDirective?: ThreeMaterial;
@Directive({
selector: 'ngt-box-geometry',
exportAs: 'ngtBoxGeometry',
providers: [{provide: ThreeGeometry, useExisting: BoxGeometryDirective}]
})
export class BoxGeometryDirective extends ThreeGeometry<THREE.BoxGeometry> {
@Input() set args(v: ConstructorParameters<typeof THREE.BoxGeometry>) {
/* ... */
}
ngOnInit() {
this.init();
}
protected init() {
this.geometry = new THREE.BoxGeometry(/* ... */);
}
}