Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Angular 2のRenderer

2,020 views

Published on

Angular 2のRendererで遊んでみます

Published in: Technology
  • Be the first to comment

Angular 2のRenderer

  1. 1. Angular 2のRenderer おのうえ (@_likr) ng-kyoto Angular Meetup #4
  2. 2. 自己紹介 • おのうえ (@_likr) • 京都大学 政策のための科学ユニット 特定助教 🆕 • ng-kyoto オーガナイザー
 GDG神戸 スタッフ • 可視化アプリケーションの
 Webベース実装
  3. 3. Renderer ?
  4. 4. Renderer • https://angular.io/docs/ts/latest/api/core/Renderer-class.html • WHAT IT DOES • Not yet documented • HOW TO USE • Not yet documented
  5. 5. Not yet documented
  6. 6. はじめに • Angular 2のRendererで遊んでみる • 明日使えなくなっても泣かない
  7. 7. Rendererの概要 • RootRenderer • Rendererを返す • Renderer • レンダリングする • DomRenderer (default) • WorkerRenderer • DebugDomRenderer • RootRendererをDIする
  8. 8. 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
  9. 9. 簡単な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
  10. 10. 自作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
  11. 11. 動かす https://plnkr.co/edit/ifMaZknans8yAAA8sSAV
  12. 12. 何かできないかな?
  13. 13. もしかして • Angularで3Dグラフィックスができるのでは!? • Scene Graph • 宣言的に3Dオブジェクトを作成 • Change Detectionの恩恵 • イベントハンドリングの抽象化
  14. 14. 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); } }
  15. 15. THREE.jsベースのRenderer class 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; // … } } }
  16. 16. 描画してみる https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC import {Component} from "angular2/core" @Component({ selector: 'my-app', template: '<three-box></three-box>', }) export class AppComponent { }
  17. 17. 描画してみる https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC
  18. 18. 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)'; }
  19. 19. Data Bindingできる https://plnkr.co/edit/H4D1gmksKC0LH5AKHA3i
  20. 20. 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
  21. 21. ChangeDetectionが効く https://plnkr.co/edit/EbqstFqCrsyVkZqLSWfY
  22. 22. 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()); } }
  23. 23. ngForも使える https://plnkr.co/edit/SAxskSugUVmBWFFcfiMC
  24. 24. 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
  25. 25. 嬉しい!
  26. 26. でも、
  27. 27. こんなことやる APIじゃないと思う
  28. 28. まとめ • Renderer APIでHTMLのレンダリングをカスタマイズ • One Framework • Angular 2は、Component指向で構築された
 XMLっぽい文書を解釈して
 UIっぽい何かを開発するフレームワーク!? • 多分違う • ご利用は計画的に
  29. 29. Discussion

×