angular 2のrenderer

29
Angular 2Renderer おのうえ (@_likr) ng-kyoto Angular Meetup #4

Upload: yosuke-onoue

Post on 14-Feb-2017

718 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: Angular 2のRenderer

Angular 2のRendererおのうえ (@_likr) ng-kyoto Angular Meetup #4

Page 2: Angular 2のRenderer

自己紹介

• おのうえ (@_likr)

• 京都大学 政策のための科学ユニット 特定助教 🆕

• ng-kyoto オーガナイザーGDG神戸 スタッフ

• 可視化アプリケーションのWebベース実装

Page 3: Angular 2のRenderer

Renderer ?

Page 4: Angular 2のRenderer

Renderer

• https://angular.io/docs/ts/latest/api/core/Renderer-class.html

• WHAT IT DOES • Not yet documented

• HOW TO USE • Not yet documented

Page 5: Angular 2のRenderer

Not yet documented

Page 6: Angular 2のRenderer

はじめに

• Angular 2のRendererで遊んでみる

• 明日使えなくなっても泣かない

Page 7: Angular 2のRenderer

Rendererの概要

• RootRenderer • Rendererを返す

• Renderer • レンダリングする • DomRenderer (default) • WorkerRenderer • DebugDomRenderer

• RootRendererをDIする

Page 8: Angular 2のRenderer

RendererのInterface

• selectRootElement • createElement • createViewRoot • createTemplateAnchor • createText • projectNodes • attachViewAfter • detachView • destroyView

• listen • listenGlobal • setElementProperty • setElementAttribute • setBindingDebugInfo • setElementClass • setElementStyle • invokeElementMethod • setText

https://angular.io/docs/ts/latest/api/core/Renderer-class.html

Page 9: Angular 2のRenderer

簡単なRendererを作る

import {Injectable} from 'angular2/core'; import { Renderer, RootRenderer, RenderComponentType, RenderDebugInfo

} from 'angular2/src/core/render/api';

@Injectable() export class MyRootRenderer implements RootRenderer { renderComponent(componentProto: RenderComponentType): Renderer { return new MyRenderer(); } }

class MyRenderer implements Renderer { selectRootElement(selectorOrNode: string | any, debugInfo: RenderDebugInfo) : any { console.log('selectRootElement', selectorOrNode, debugInfo); return {}; } createElement(parentElement: any, name: string, debugInfo: RenderDebugInfo) : any { console.log('createElement', parentElement, name, debugInfo); return {}; } // … }

my-renderer.ts

Page 10: Angular 2のRenderer

自作Rendererを使う

import {Component} from 'angular2/core';

@Component({ selector: 'my-app', template: '<h1>My First Angular 2 App</h1>' }) export class AppComponent { }

import {provide, RootRenderer} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser'; import {AppComponent} from './app.component'; import {MyRootRenderer} from './my-renderer'

bootstrap(AppComponent, [ provide(RootRenderer, { useClass: MyRootRenderer }), ]);

app.component.ts

main.ts

Page 11: Angular 2のRenderer

動かす

https://plnkr.co/edit/ifMaZknans8yAAA8sSAV

Page 12: Angular 2のRenderer

何かできないかな?

Page 13: Angular 2のRenderer

もしかして

• Angularで3Dグラフィックスができるのでは!?

• Scene Graph • 宣言的に3Dオブジェクトを作成

• Change Detectionの恩恵

• イベントハンドリングの抽象化

Page 14: Angular 2のRenderer

THREE.jsベースのRenderer

import {Injectable} from 'angular2/core'; import { Renderer, RootRenderer, RenderComponentType, RenderDebugInfo

} from 'angular2/src/core/render/api';

@Injectable() export class MyRootRenderer implements RootRenderer { scene: THREE.Scene; camera: THREE.Camera; renderer: THREE.WebGLRenderer; constructor() { this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000); this.camera.position.z = 5; this.renderer = new THREE.WebGLRenderer(); } renderComponent(componentProto: RenderComponentType): Renderer { return new MyRenderer(this); } }

Page 15: Angular 2のRenderer

THREE.jsベースのRendererclass MyRenderer implements Renderer { constructor(private rootRenderer: MyRootRenderer) { } selectRootElement(selector: string, debugInfo: RenderDebugInfo) : any { var element = document.querySelector(selector); this.rootRenderer.renderer.setSize(600, 600); element.innerHTML = ''; element.appendChild(this.rootRenderer.renderer.domElement); var render = () => { requestAnimationFrame(render); this.rootRenderer.renderer.render(this.rootRenderer.scene, this.rootRenderer.camera); }; render(); return this.rootRenderer.scene; } createElement(parentElement: any, name: string, debugInfo: RenderDebugInfo) : any { switch (name) { case 'three-box': var geometry = new THREE.BoxGeometry(1, 1, 1); var material = new THREE.MeshBasicMaterial(); var cube = new THREE.Mesh(geometry, material); this.rootRenderer.scene.add(cube); return cube; // … default: throw 'unknown element'; } } setElementAttribute(renderElement: any, attributeName: string, attributeValue: string) : void { switch (attributeName) { case 'color': renderElement.material.color = new THREE.Color(attributeValue); break; // … } } }

Page 16: Angular 2のRenderer

描画してみる

https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC

import {Component} from "angular2/core"

@Component({ selector: 'my-app', template: '<three-box></three-box>', }) export class AppComponent { }

Page 17: Angular 2のRenderer

描画してみる

https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC

Page 18: Angular 2のRenderer

Data Bindingできる

https://plnkr.co/edit/H4D1gmksKC0LH5AKHA3i

import {Component} from "angular2/core"

@Component({ selector: 'my-app', template: ` <three-box [attr.color]="boxColor"> </three-box> `, }) export class AppComponent { boxColor = 'rgb(0, 255, 0)'; }

Page 19: Angular 2のRenderer

Data Bindingできる

https://plnkr.co/edit/H4D1gmksKC0LH5AKHA3i

Page 20: Angular 2のRenderer

import {Component, OnInit} from "angular2/core"

@Component({ selector: 'my-app', template: ` <three-box [attr.color]="boxColor" [attr.rotationX]="rotationX" [attr.rotationY]="rotationY"> </three-box> `, }) export class AppComponent implements OnInit { boxColor = 'rgb(0, 255, 0)'; rotationX = 0; rotationY = 0; ngOnInit() { this.updateRotation(); } updateRotation() { this.rotationX += 0.1; this.rotationY += 0.1; requestAnimationFrame(() => this.updateRotation()); } }

ChangeDetectionが効く

https://plnkr.co/edit/EbqstFqCrsyVkZqLSWfY

Page 21: Angular 2のRenderer

ChangeDetectionが効く

https://plnkr.co/edit/EbqstFqCrsyVkZqLSWfY

Page 22: Angular 2のRenderer

ngForも使える

https://plnkr.co/edit/SAxskSugUVmBWFFcfiMC

import {Component, OnInit} from "angular2/core"

@Component({ selector: 'my-app', template: ` <three-box *ngFor="let box of boxes" [attr.color]="box.color" [attr.positionX]="box.x" [attr.rotationX]="rotationX" [attr.rotationY]="rotationY"> </three-box> `, }) export class AppComponent implements OnInit { boxes = [ {color: 'rgb(255, 0, 0)', x: -3}, {color: 'rgb(0, 255, 0)', x: 0}, {color: 'rgb(0, 0, 255)', x: 3}, ]; rotationX = 0; rotationY = 0; ngOnInit() { this.updateRotation(); } updateRotation() { this.rotationX += 0.1; this.rotationY += 0.1; requestAnimationFrame(() => this.updateRotation()); } }

Page 23: Angular 2のRenderer

ngForも使える

https://plnkr.co/edit/SAxskSugUVmBWFFcfiMC

Page 24: Angular 2のRenderer

import {Component, OnInit} from "angular2/core" var rotateColor = (box) => { switch (box.color) { case 'rgb(255, 0, 0)': box.color = 'rgb(0, 255, 0)'; break; case 'rgb(0, 255, 0)': box.color = 'rgb(0, 0, 255)'; break; case 'rgb(0, 0, 255)': default: box.color = 'rgb(255, 0, 0)'; } }; @Component({ selector: 'my-app', template: ` <three-box *ngFor="let box of boxes" [attr.color]="box.color" [attr.positionX]="box.x" [attr.rotationX]="rotationX" [attr.rotationY]="rotationY" (click)="handleClick(box)"> </three-box> `, }) export class AppComponent implements OnInit{ boxes = [ {color: 'rgb(255, 0, 0)', x: -3}, {color: 'rgb(0, 255, 0)', x: 0}, {color: 'rgb(0, 0, 255)', x: 3}, ]; rotationX = 0; rotationY = 0; ngOnInit() { this.updateRotation(); } updateRotation() { this.rotationX += 0.1; this.rotationY += 0.1; requestAnimationFrame(() => this.updateRotation()); } handleClick(box) { rotateColor(box); } }

EventHandlingもできる

https://plnkr.co/edit/uy6oUMVoUc1DQ0YSvG8V

Page 25: Angular 2のRenderer

嬉しい!

Page 26: Angular 2のRenderer

でも、

Page 27: Angular 2のRenderer

こんなことやる APIじゃないと思う

Page 28: Angular 2のRenderer

まとめ

• Renderer APIでHTMLのレンダリングをカスタマイズ

• One Framework • Angular 2は、Component指向で構築された

XMLっぽい文書を解釈して

UIっぽい何かを開発するフレームワーク!?

• 多分違う • ご利用は計画的に

Page 29: Angular 2のRenderer

Discussion