SlideShare a Scribd company logo
Angular 2のRenderer
おのうえ (@_likr)
ng-kyoto Angular Meetup #4
自己紹介
• おのうえ (@_likr)
• 京都大学 政策のための科学ユニット 特定助教 🆕
• ng-kyoto オーガナイザー

GDG神戸 スタッフ
• 可視化アプリケーションの

Webベース実装
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
Not yet documented
はじめに
• Angular 2のRendererで遊んでみる
• 明日使えなくなっても泣かない
Rendererの概要
• RootRenderer
• Rendererを返す
• Renderer
• レンダリングする
• DomRenderer (default)
• WorkerRenderer
• DebugDomRenderer
• RootRendererをDIする
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
簡単な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
自作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
動かす
https://plnkr.co/edit/ifMaZknans8yAAA8sSAV
何かできないかな?
もしかして
• Angularで3Dグラフィックスができるのでは!?
• Scene Graph
• 宣言的に3Dオブジェクトを作成
• Change Detectionの恩恵
• イベントハンドリングの抽象化
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);
}
}
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;
// …
}
}
}
描画してみる
https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC
import {Component} from "angular2/core"
@Component({
selector: 'my-app',
template: '<three-box></three-box>',
})
export class AppComponent {
}
描画してみる
https://plnkr.co/edit/yB0J8nVBK0KUiwkFO1VC
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)';
}
Data Bindingできる
https://plnkr.co/edit/H4D1gmksKC0LH5AKHA3i
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
ChangeDetectionが効く
https://plnkr.co/edit/EbqstFqCrsyVkZqLSWfY
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());
}
}
ngForも使える
https://plnkr.co/edit/SAxskSugUVmBWFFcfiMC
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
嬉しい!
でも、
こんなことやる
APIじゃないと思う
まとめ
• Renderer APIでHTMLのレンダリングをカスタマイズ
• One Framework
• Angular 2は、Component指向で構築された

XMLっぽい文書を解釈して

UIっぽい何かを開発するフレームワーク!?
• 多分違う
• ご利用は計画的に
Discussion

More Related Content

PDF
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
ODP
JavascriptMVC
PDF
ECMA2015 INSIDE
PDF
React Native Internals
PDF
Testing in JavaScript
ODP
Gradle - next generation of build tools
PPT
Angular tips
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
JavascriptMVC
ECMA2015 INSIDE
React Native Internals
Testing in JavaScript
Gradle - next generation of build tools
Angular tips

More from Yosuke Onoue (19)

PDF
アニメーション(のためのパフォーマンス)の基礎知識
PDF
AngularJSでデータビジュアライゼーションがしたい
PDF
GDG DevFest Kobe Firebaseハンズオン勉強会
PDF
Polymerやってみた
PDF
asm.jsとWebAssemblyって実際なんなの?
PDF
AngularFireで楽々バックエンド
PDF
AngularJSとD3.jsによるインタラクティブデータビジュアライゼーション
PDF
AngularJSでの非同期処理の話
PDF
社会的決定とAHP
PDF
CUDA 6の話@関西GPGPU勉強会#5
PDF
Anaconda & NumbaPro 使ってみた
PDF
PythonistaがOCamlを実用する方法
KEY
What's New In Python 3.3をざっと眺める
KEY
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
KEY
PyOpenCLによるGPGPU入門
PPTX
数理最適化とPython
PPTX
201010ksmap
PPTX
PyCUDAの紹介
PPT
Rsa暗号で彼女が出来るらしい
アニメーション(のためのパフォーマンス)の基礎知識
AngularJSでデータビジュアライゼーションがしたい
GDG DevFest Kobe Firebaseハンズオン勉強会
Polymerやってみた
asm.jsとWebAssemblyって実際なんなの?
AngularFireで楽々バックエンド
AngularJSとD3.jsによるインタラクティブデータビジュアライゼーション
AngularJSでの非同期処理の話
社会的決定とAHP
CUDA 6の話@関西GPGPU勉強会#5
Anaconda & NumbaPro 使ってみた
PythonistaがOCamlを実用する方法
What's New In Python 3.3をざっと眺める
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門
数理最適化とPython
201010ksmap
PyCUDAの紹介
Rsa暗号で彼女が出来るらしい
Ad

Angular 2のRenderer