Zpět

Vue.js & A-Frame

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

  • 
    <div class="fixed-ratio">
        <!-- A-Frame scéna -->
        <a-scene embedded>
    	    <a-text
    		    :value="text"
    		    :color="diffuseColor"
    		    align="center"
    		    position="0 0 -0.5">
    	    </a-text>
        </a-scene>
    </div>
    <div>
        <!-- Formulář pro ovládání scény -->
        <form>
    	    <div>
    		    <label>Text</label>
                <!-- Vstup pro text s obousměrným data-bindingem v-model -->
    		    <input type="text" v-model="text" />
    	    </div>
    	    <div class="grid">
    		    <div>
    			    <label>Základní barva</label>
    			    <div>
    				    <input type="color" v-model="diffuseColor" />
    				    <span :style="'color: ' + diffuseColor"> {{ diffuseColor }} </span>
    			    </div>
    		    </div>
    	    </div>
        </form>
    </div>
    
  • // Vue aplikace
    var app1 = new Vue({
        el: '#app1',
        data: {
            text: 'Hello world!',
            diffuseColor: '#dd3300'
        }
    });
    
{{ diffuseColor }}

Ukázka #2 - Práce s polem

  • 
    <div class="fixed-ratio">
        <!-- A-Frame scéna -->
        <a-scene embedded>
            <!-- Cyklus s využitím directivy v-for pro vykreslení všech kostek -->
    	    <a-entity v-for="(item, index) in items">
    		    <a-entity :position="((index - ((items.length - 1) / 2)) * 2) + ' 0 -5'">
    			    <a-box :color="item.color"
    				       :width="item.size.x"
    				       :height="item.size.y"
    				       :depth="item.size.z"
    				       :position="item.position.x + ' ' + item.position.y + ' ' + item.position.z">
    			    </a-box>
    		    </a-entity>
    	    </a-entity>
        </a-scene>
    </div>
    <div>
        <!-- Formulář pro ovládání scény -->
        <form>
            <ul>
                <!-- Cyklus s využitím directivy v-for pro ovládací panely ke všem kostkám -->
                <li v-for="(item, index) in items">
                    <div class="grid">
                        <div>
                            <label>Objekt #{{index + 1}}</label>
                            <div>
                                <input type="color" v-model="item.color" />
                                <span :style="'color: ' + item.color"> {{ item.color }} </span>
                            </div>
                        </div>
                        <div>
                            <label>Šířka {{ Math.floor(item.size.x * 100) }}%</label>
                            <input type="range" v-model="item.size.x" min="0.1" max="2" step="0.1" />
                        </div>
                        <div>
                            <label>Výška {{ Math.floor(item.size.y * 100) }}%</label>
                            <input type="range" v-model="item.size.y" min="0.1" max="2" step="0.1" />
                        </div>
                        <div>
                            <label>Délka {{ Math.floor(item.size.z * 100) }}%</label>
                            <input type="range" v-model="item.size.z" min="0.1" max="2" step="0.1" />
                        </div>
                        <div>
                            <label>X {{ item.position.x }}</label>
                            <input type="range" v-model="item.position.x" min="-1" max="1" step="0.1" />
                        </div>
                        <div>
                            <label>Y {{ item.position.y }}</label>
                            <input type="range" v-model="item.position.y" min="-1" max="1" step="0.1" />
                        </div>
                        <div>
                            <label>Z {{ item.position.z }}</label>
                            <input type="range" v-model="item.position.z" min="-1" max="1" step="0.1" />
                        </div>
                        <div>
                            <!-- Tlačítko napojené na metodu pro smazání kostky -->
                            <a v-on:click="remove(index)">Smazat</a>
                        </div>
                    </div>
                </li>
            </ul>
            <!-- Tlačítko napojené na metodu pro přidání kostky -->
            <a v-on:click="add()" > Přidat nový objekt</a>
        </form>
    </div>
    
  • // Vue aplikace
    var app2 = new Vue({
        el: '#app2',
        data: {
            items: [],
        },
        methods: {
            // metoda pro přidání kostky
            add: function () {
                this.items.push({
                    size: { x: 1, y: 1, z: 1 },
                    position: { x: 0, y: 0, z: 0 },
                    color: getRandomColor()
                });
            },
            // metoda pro smazání kostky
            remove: function (index) {
                this.items.splice(index, 1);
            }
        },
        // metoda volaná při inicializaci
        created: function () {
            this.add();
            this.add();
        }
    });
    
  • {{ item.color }}
Přidat nový objekt

Ukázka #3 - Pokročilejší scéna

  • 
    <a-scene embedded>
    	<a-entity position="0 0 0" camera look-controls></a-entity>
    	<a-entity rotation="80 0 0" position="0 0 -10">
    		<a-box color="#0D660D" width="16" height="0.1" depth="6" position="0 -0.05 0"></a-box>
    		<a-text value="LED diody (8 bitu)" height="40" width="20" color="#ff9900" align="center" position="0 0.01 -1.8" rotation="-90 0 0"></a-text>
    		<a-entity v-for="(led, index) in leds">
    			<a-entity :position="((((leds.length - index) - (leds.length / 2)) * 2) - 1) + ' 0 0'">
    				<a-text :value="Math.pow(2, index)" height="20" width="10" color="#ff9900" align="center" position="0 0.01 1" rotation="-90 0 0"></a-text>
    				<a-entity position="0 0.15 -0.25">
    					<a-sphere position="0 0.95 0"
    							  radius="0.6"
    							  :color="(led.state ? color : '#CCCCCC')"
    							  opacity="0.8">
    					</a-sphere>
    					<a-cylinder position="0 0.55 0"
    								height="0.8"
    								radius="0.6"
    								:color="(led.state ? color : '#CCCCCC')"
    								opacity="0.8">
    					</a-cylinder>
    					<a-cylinder height="0.3"
    								radius="0.66"
    								:color="(led.state ? color : '#CCCCCC')"
    								opacity="0.8">
    					</a-cylinder>
    				</a-entity>
    				<a-entity position="0 0.25 2">
    					<a-cylinder position="0 0.35 0"
    								:height="led.state ? 0.2 : 0.6"
    								radius="0.66"
    								color="#8080CC"
                                    data-clickable
                                    :onclick="'app3.lightSwitch(' + index + ')'">
    					</a-cylinder>
    					<a-box width="1.4" height="0.5" depth="1.4" color="#1A1A1A"></a-box>
    				</a-entity>
    			</a-entity>
    		</a-entity>
    	</a-entity>
    </a-scene>
    
  • // Vue aplikace
    var app3 = new Vue({
        el: '#app3',
        data: {
            leds: [
                { state: false },
                { state: true },
                { state: false },
                { state: false },
                { state: true },
                { state: true },
                { state: false },
                { state: false },
            ],
            color: '#ff0000',
        },
        // dopočítáváné vlastnosti pro hexadecimální a binární zápis
        computed: {
            int: {
                get: function () {
                    var r = 0;
                    for (var i = 0; i < this.leds.length; i++) {
                        r += this.leds[i].state ? Math.pow(2, i) : 0;
                    }
                    return r;
                },
                set: function (v) {
                    var bin = toBin(v);
                    for (var i = 0; i < this.leds.length; i++) {
                        this.leds[this.leds.length - i - 1].state = bin[i] == "1";
                    }
                }
            },
            hex: {
                get: function () { return toHex(this.int); },
                set: function (v) { this.int = parseInt(v, 16); }
            },
            bin: {
                get: function () { return toBin(this.int); },
                set: function (v) { this.int = parseInt(v, 2); }
            }
        },
        methods: {
            // metoda pro přepnutí LED diody
            lightSwitch: function (index) {
                this.leds[index].state = !this.leds[index].state;
            }
        }
    });
    
  • 
    <form>
    	<div>
    		<label>
    			<span class="left">0</span>
    			<span class="right">255</span>
    		</label>
    		<div>
    			<input type="range" v-model="int" min="0" max="255" step="1" />
    		</div>
    	</div>
    	<div>
    		<div class="grid">
    			<div>
    				<label>Číslo</label>
    				<input type="text" v-model="int" />
    			</div>
    			<div>
    				<label>Binární zápis</label>
    				<input type="text" v-model="bin" />
    			</div>
    			<div>
    				<label>Hexadecimální zápis</label>
    				<input type="text" v-model="hex" />
    			</div>
    			<div>
    				<label>Barva světla</label>
    				<input type="color" v-model="color" />
    				<span :style="'color: ' + color"> {{ color }} </span>
    			</div>
    		</div>
    	</div>
    </form>
    
{{ color }}