Zpět

Angular & PlayCanvas

Ukázka #1 - Data-binding do 3D scény

  • 
    // import jádra Angularu
    import { Component } from '@angular/core';
    
    // konstanty pro moduly načítané pomocí tagu script
    declare const MW: any;
    declare const pc: any;
    declare const setupScene: any;
    declare const MAP: any;
    
    // decorator Angular komponentu
    @Component({
      selector: 'app1',
      templateUrl: './app1.component.html' // URL šablony
    })
    // třída Angular komponentu
    export class App1Component {
      data = {};
    
      // metoda pro inicializaci komponentu
      ngOnInit() {
        var that = this;
        var data = {};
        var scene = setupScene("canvas1"); // vytvoření scény 
    
        // načtení fontu
        var font = new pc.Asset('Arial.json', "font", { url: "../../../libs/playcanvas/Arial.json" });
        scene.assets.on('load', function () {
    
            // entita pro text
            var text = new pc.Entity("text", scene);
            text.addComponent("element", {
                type: "text",
                anchor: [0, 0, 0, 0],
                pivot: [0.5, 0.5],
                fontSize: 16,
                fontAsset: font,
                opacity: 1,
                color: [0, 0, 1],
                shadowColor: [0, 0, 1],
                shadowOffset: [0.2, -0.2],
                text: "Hello World!"
            });
            text.setLocalScale(1 / 32, 1 / 32, 1 / 32);
            scene.root.addChild(text);
    
            // obousměrné mapování mezi 3D objektem a datovým objektem 
            new MW.TwoWayMap({
                end1: data,
                map1: MAP.TEXT.to3DModel,
                end2: text,
                map2: MAP.TEXT.toDataModel,
                data1: {
                    text: 'Hello world!',
                    diffuseColor: '#dd3300',
                    outlineColor: '#ee9966'
                }
            });
            that.data = data;
        });
        scene.assets.add(font);
        scene.assets.load(font);
      }
    }
    
  • 
    <div class="fixed-ratio">
        <!-- Plátno pro scénu -->
        <canvas id="canvas1" "></canvas>
    </div>
    <div>
        <!-- Formulář pro ovládání scény -->
        <form>
            <div>
                <label>Text</label>
                <div>
                  <!-- Vstup pro text s obousměrným data-bindingem [(ngModel)] -->
                  <input name="text" type="text" [(ngModel)]="text" />
                </div>
            </div>
            <div>
                <div class="grid">
                    <div>
                        <label>Základní barva</label>
                        <div>
                            <input name="diffuse" type="color" [(ngModel)]="diffuseColor" />
                            <span [ngStyle]="{'color': diffuseColor }"> {{ diffuseColor }} </span>
                        </div>
                    </div>
                    <div>
                        <label>Barva lesku</label>
                        <div>
                            <input name="specular" type="color" [(ngModel)]="specularColor" />
                            <span [ngStyle]="{'color': specularColor }"> {{ specularColor }} </span>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </div>
    
  • 
    import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    
    import { App1Component } from './app1.component';
    
    @NgModule({
      imports:      [ BrowserModule, FormsModule ],
      declarations: [ App1Component ],
      bootstrap:    [ App1Component ],
      schemas:      [ NO_ERRORS_SCHEMA ]
    })
    export class AppModule { }
    

Ukázka #2 - Práce s polem

  • 
    // import jádra Angularu
    import { Component } from '@angular/core';
        
    // konstanty pro moduly načítané pomocí tagu script
    declare const MW: any;
    declare const pc: any;
    declare const setupScene: any;
    declare const MAP: any;
    
    // decorator Angular komponentu
    @Component({ 
      selector: 'app2',
      templateUrl: './app2.component.html'
    })
    // třída Angular komponentu
    export class App2Component {
      items = [];
      group  = new THREE.Group();
    
      // vytvoření scény při inicializaci komponentu
      ngOnInit() { 
        this.scene = setupScene("canvas2");
        this.group = new pc.Entity("group", this.scene);
        this.group.setLocalScale(0.2, 0.2, 0.2);
        this.scene.root.addChild(this.group);
        this.add();
        this.add();
      }
    
      // metoda pro vytvoření kostky
      createCube(index) {
        var data = {};
    
        // entita kostky
        var cube = new pc.Entity("box" + index, this.scene);
        cube.addComponent("model", { type: "box" });
        var material = new pc.StandardMaterial();
        material.update();
        cube.model.material = material;
        this.group.addChild(cube);
    
        // obousměrné mapování mezi 3D objektem a datovým objektem
        new MW.TwoWayMap({
            end1: data,
            map1: MAP.CUBE.to3DModel,
            end2: cube,
            map2: MAP.CUBE.toDataModel,
            data1: {
                color: "#ff9900",
                element: cube,
                index: index
            }
        });
    
        // relativní pozice kostky
        this.group.setLocalPosition(-index * 0.2, 0, 0);
        cube.setLocalPosition(index * 2, 0, 0);
        return data;
      }
    
      // metoda pro přidání kostky
      add() {
        this.items.push(this.createCube(this.items.length));
      }
    
      // metoda pro smazání kostky
      remove(index) {
        var mesh = this.items[index].element;
        this.group.removeChild(mesh);
        mesh.destroy();
        this.items.splice(index, 1);
        // přepočet pozice a indexu u dalších kostek
        for (var i = index; i < this.items.length; i++) {
            this.items[i].index = i;
            var original = this.items[i].element.getLocalPosition();
            original.x = original.x - 2;
            this.items[i].element.setLocalPosition(original);
        }
        this.group.setLocalPosition(- (this.items.length - 1) * 0.2, 0, 0);
      }
    }
    
  • 
    <div class="fixed-ratio">
        <!-- Plátno pro scénu -->
        <canvas id="canvas2" "></canvas>
    </div>
    <div>
        <!-- Formulář pro ovládání scény -->
        <form>
            <ul>
                <!-- Cyklus s využitím directivy *ngFor pro ovládací panely ke všem kostkám -->
                <li *ngFor="let item of items; index as index">
                    <div>
                        <div class="grid">
                            <div>
                                <label>Objekt #{{index + 1}}</label>
                                <div>
                                    <input type="color" [(ngModel)]="item.color" name="color {{ index }}" />
                                    <span [ngStyle]="{'color': item.color }"> {{ item.color }} </span>
                                </div>
                            </div>
                            <div>
                                <div class="grid">
                                    <div>
                                        <label>↔ W {{ item.size.x * 100 }}%</label>
                                        <input type="range" [(ngModel)]="item.size.x" min="0.1" max="2" step="0.1" name="w{{ index }}" />
                                    </div>
                                    <div>
                                        <label>↕ H {{ item.size.y * 100 }}%</label>
                                        <input type="range" [(ngModel)]="item.size.y" min="0.1" max="2" step="0.1" name="h{{ index }}" />
                                    </div>
                                    <div>
                                        <label>⤢ L {{ item.size.z * 100 }}%</label>
                                        <input type="range" [(ngModel)]="item.size.z" min="0.1" max="2" step="0.1" name="l{{ index }}" />
                                    </div>
                                    <div>
                                        <label>→ X {{ item.position.x }}</label>
                                         <input type="range" [(ngModel)]="item.position.x" min="-1" max="1" step="0.1" name="x{{ index }}" />
                                    </div>
                                    <div>
                                        <label>↑ Y {{ item.position.y }}</label>
                                        <input type="range" [(ngModel)]="item.position.y" min="-1" max="1" step="0.1" name="y{{ index }}" />
                                    </div>
                                    <div>
                                        <label>↗ Z {{ item.position.z }}</label>
                                        <input type="range" [(ngModel)]="item.position.z" min="-1" max="1" step="0.1" name="z{{ index }}" />
                                    </div>
                                </div>
                            </div>
                            <div>
                                <!-- Tlačítko napojené na metodu pro smazání kostky -->
                                <a (click)="remove(index)">Smazat</a>
                            </div>
                        </div>
                    </div>
                </li>
            </ul>
            <!-- Tlačítko napojené na metodu pro přidání kostky -->
            <a (click)="add()">Přidat nový objekt</a>
        </form>
    </div>
    
  • 
    import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    
    import { App2Component } from './app2.component';
    
    @NgModule({
      imports:      [ BrowserModule, FormsModule ],
      declarations: [ App2Component ],
      bootstrap:    [ App2Component ],
      schemas:      [ NO_ERRORS_SCHEMA ]
    })
    export class AppModule { }
    
  • #a94c12
  • #805ad1
Přidat nový objekt