Virtual-Reality-Projekte erstellen: So geht’s mit Vue.js und A-Frame
Der 8. August 2017 war ein wichtiger Tag für den WebVR-Standard. An jenem Tag integrierte Mozilla in dem offiziellen Release 55 von Firefox die Technologie – ein wichtiger Schritt für Virtual Reality im Web. Einige mobile Browser hatten schon vorgelegt, unter anderem Samsung Internet für die Gear VR, der Oculus Browser und allen voran die mobile Variante des Chrome-Browsers. Weitere Browser und Betriebssysteme folgten.
Es ist aber auch die wachsende Zahl an Entwicklerwerkzeugen, die die Erstellung von VR-Anwendungen möglich machen. Libraries wie React VR, PlayCanvas, Primrose VR und A-Frame wachsen und gedeihen. Daneben entstehen Werkzeuge wie Blocks von Google zur Erstellung von 3D-Content sowie unzählige Erweiterungen für A-Frame – etwa für Multi-User-VR-Anwendungen mit Hilfe von Networked-Aframe.
A-Frame war eine der ersten und ist derzeit eine der meistgenutzten WebVR-Lösungen. Das liegt daran, dass A-Frame so einfach zugänglich ist und andere Libraries nahtlos integriert. Die wichtigsten Weiterentwicklungen des Werkzeugs sind der A-Frame Inspector, die A-Frame Registry (eine Sammlung der besten Komponenten) und die Motion-Capture-Komponente, die das Testen einer VR-App stark vereinfacht. Ganz neu ist außerdem die Link-Komponente. Mit ihr können Entwickler mehrere VR-Seiten verknüpfen – unter anderem durch Portale –, ohne dass Nutzer die VR-Erfahrung verlassen müssen: ein wichtiger Aspekt, denn die Verlinkung verschiedener Seiten macht das Web schließlich erst aus.
VUE.JS: Komplexität auflösen
In den vergangenen Jahren entstand in der 2D-Webentwicklung die Notwendigkeit für eine klare Struktur in datengetriebenen Anwendungen – im Gegensatz zur händischen DOM-Manipulation aus frühen jQuery-Zeiten. Sobald Webworker in der VR-Entwicklung fürs Web über den einfachen Prototypen hinaus wollen, werden diese Anforderungen auch hier schnell deutlich. Daher ist die nahtlose Kombination aus A-Frame und Vue.js oder ähnlichen Frameworks ein unbedingtes Muss für jedes größere Virtual-Reality-Projekt im Web: zum Beispiel für einen WebVR-Shop, der an ein CMS angebunden ist und Artikel dynamisch ausliest; oder für eine WebVR-Anwendung, die 3D-Diagramme auf Basis laufender Events live erzeugt; oder eine WebVR-App, die Daten aus Social-Media-Kanälen nutzt. Die Liste an Beispielen ließe sich fortsetzen.
Dabei ist Vue.js nicht ohne Grund beliebt: Es ist schlank und vereint die besten Aspekte moderner Frontend-Frameworks. Es hilft bei einer saubereren Struktur der Elemente im HTML-DOM, der Interaktivität durch das Event-Handling und beim dynamischen Generieren von Inhalten – etwa durch Daten von APIs oder für Multi-User-Erfahrungen. Nicht zuletzt passen die beiden Frameworks ideal zusammen, da sie beide einen starken Schwerpunkt auf die Komposition von Komponenten legen. Einen guten Einstieg in das Framework bietet die offizielle Website.
Praxi-Demo: API-Getriebene Webvr-Anwendung
Der Grundaufbau eines WebVR-Projekts mit A-Frame ist einfach: Entwickler laden das Framework in ihre HTML-Datei, initialisieren eine neue VR-Szene mit Hilfe des HTML-Elements a-scene
und laden die Vue.js-Datei hinzu. A-Frame kümmert sich automatisch um alle relevanten Details der Konfiguration und Kompatibilität mit dem Anwendergerät – egal ob VR-Brille, Smartphone oder regulärer Browser.
<html> <head> <script src=“https://unpkg.com/vue“></script> <script src=“https://unpkg.com/aframe“></script> </head> <body> <a-scene id=“scene“></a-scene> </body> </html>
Das Szene-Element hat eine ID erhalten, sodass es sich in Javascript referenzieren lässt. Die Initialisierung von Vue ist ähnlich simpel: Entwickler erstellen eine neue Vue-Instanz und übergeben dabei die eben erwähnte ID und ein vorerst leeres Array, das seine Daten später über die API von Giphy.com erhält.
<script type=“text/javascript“> var scene = new Vue({ el: '#scene', data: { items: [] } }) </script>
Nun geht es an den spannenden Teil: Aus der Komponente a-gif
, die im nächsten Schritt entsteht, erzeugen Webworker dynamisch Elemente innerhalb der VR-Szene und binden diese mit Hilfe von v-for
an das Array items
der Vue-Instanz. Mit dieser Verbindung sorgt Vue.js ganz automatisch für die Manipulation der DOM-Elemente, je nachdem, wie Developer das Array verändern und beispielsweise neue Daten von der API einladen.
<a-scene id=“scene“><a-gif v-for=“item in items“ :data=“ item“ :key=“item.id“></a-gif></a-scene>
Durch das Entkoppeln der Komponente a-gif
erhalten Entwickler eine saubere Struktur und können im kleinen Rahmen die Anforderungen des Elements definieren. Außerdem garantiert die Trennung eine hohe Wiederverwendbarkeit und einen guten Überblick bei komplexen Projekten. Das Template in diesem Beispiel nutzt das Objekt a-plane
aus der Grundausstattung von A-Frame. Es erhält die dynamisch berechneten Attribute für die Breite, Höhe und das Material. Diese drei Werte ziehen Webworker aus den Daten, die sie von der Giphy-API erhalten, und formatieren sie für diese Szene etwas um – als Material für die Fläche a-plane
kommt das GIF selbst im MP4-Format zum Einsatz.
Vue.component('a-gif', { props: ['data'], template: '<a-plane :width=“width“ :height=“height“:material=“material“></a-plane>‘, computed: { width: function() { return this.data.images.preview.width / 100; }, height: function() { return this.data.images.preview.height / 100; }, material: function() { return ‚src:url(‚ + this.data.images.preview.mp4 + ')'; } } })
Nun fehlen der dynamischen VR-Anwendung nur noch die Daten. Die API von Giphy.com, die in diesem Beispiel Anwendung findet, ist kostenfrei. Den API-Key können Entwickler online erzeugen. In Kombination mit der Funktion fetch von Javascript entsteht im Handumdrehen eine Reihe toller Katzen-GIFs. Das Laden der API verpacken Entwickler in einer Methode refresh in der Vue-Instanz und rufen diese sofort auf, wenn der Vue-Lebenszyklus das Event created auslöst. Das magische Zusammenspiel von A-Frame und Vue beginnt, sobald Webworker das Ergebnis der API der Variable this.items zuweisen: Die Anwendung erzeugt die Elemente a-gif nun dynamisch und berechnet ihre Attribute entsprechend – schließlich sind die GIFs in der virtuellen Realität sichtbar.
methods: { refresh: function(event) { fetch('https://api.giphy.com/v1/gifs/search?-q=cats&api_key='+API_KEY) .then(function(response) { return response.json(); }) .then(function(items) { this.items = items.data;}.bind(this)); } }, created: function() { this.refresh(); }
Jedoch müssen sich Entwickler noch um die Platzierung der Elemente im virtuellen Raum kümmern. In folgendem Beispiel sehen wir, wie hilfreich die Flexibilität von A-Frame ist und wie einfach es ist, externe Komponenten im eigenen Projekt zu verwenden.
Im Kopfbereich der HTML-Datei laden Entwickler nun zwei weitere JS-Dateien: die Komponenten layout
und look-at
. Die Layout-Komponente platziert die GIFs in einem Kreis um den Nutzer der WebVR-Anwendung herum. Dazu liegt das Element a-gif
in einer a-entity
– also einer Wrapper-Komponente von A-Frame – auf Augenhöhe positioniert. Die Attribute von layout
beschreiben Form, Größe und Ausrichtung. Außerdem fügen Developer die Komponente look-at
mit dem simplen Zusatz look-at=“[camera]
” an den GIF-Flächen an, sodass sie sich jederzeit zum Nutzer hin drehen und so aus jeder Perspektive sichtbar sind. Fertig ist das virtuelle GIF-Rondell mit dynamisch geladenen Daten.
<script src=“https://unpkg.com/aframe-layout-component“></script> <script src=“https://unpkg.com/aframe-look-at-component“></ script> ... <a-entity layout=“type: circle; radius: 7; plane: xz;“ position=“0 1 0“><a-gif ...></a-gif></a-entity> ... Vue.component('a-gif', { ... template: '<a-plane ... look-at=“[camera]“></a-plane>' })
Um den dynamischen Aspekt voll auszunutzen, lässt sich die Anfrage an die API so anpassen, dass sie nur einen bestimmten Bereich – im Beispiel jeweils zehn GIFs – der Suchergebnisse lädt. Hierzu führen Entwickler die Variablen numItems
und page
ein und integrieren sie in die Funktion fetch
.
var numItems = 10, page = 1; [...] fetch(‚...+'&limit='+numItems+'&offset='+(page*numItems)) [...]
Für das Ändern der Variable page
und das erneute Aufrufen der Methode refresh
erstellen Developer eine weitere Komponente a-refresh
und binden sie innerhalb der <a-scene> ein. Da die Anwendung die VR-Szene komplett in WebGL rendert, müssen Webworker zusätzlich die Komponente cursor
einbauen. Sie nimmt Klick-Events von unterschiedlichen Geräten auf und gibt sie an Javascript weiter. Klickt der Anwender nun über ein Eingabegerät – eine Maus, einen Touch-Screen oder einen Motion-Controller – auf die Box, stellt die App automatisch eine neue Anfrage an die API. Die beiden Frameworks A-Frame und Vue.js kümmern sich dann um den Umbau der Elemente im virtuellen Raum.
Vue.component('a-refresh‘, { template: '<a-box @click=“handleClick“></a-box>, methods: { handleClick: function(event) { page++; scene.refresh(); } }}) ... <a-refresh></a-refresh> <a-camera><a-entity cursor [...]></a-camera>
Auf dem verlinkten GitHub-Repository gibt es den kompletten Source-Code zu diesem vereinfachten Beispiel, inklusive einer erweiterten Variante und zusätzlichen Kommentaren. Eine tolle Plattform mit vielen weiteren Beispielen zu A-Frame ist Glitch. Das Projekt „Awesome A-Frame” bietet viele Links zu weiteren Materialien.
Fazit
WebVR steht mit einem starken Toolset und einer hilfsbereiten Community in den Startlöchern. Durch dessen Integration in führende Browser wächst die Zahl potenzieller Nutzer für Virtual -Reality-Inhalte im Web stetig. Das spiegelt sich auch in der langsam zunehmenden Nachfrage von Kunden an Agenturen und Freelancer für VR-Anwendungen wider. In Verbindung mit Frameworks wie Vue.js sind zudem auch komplexere VR- Anwendungen in Verbindung mit Web-Technologien möglich. Webentwickler können daher bekannte Techniken nutzen und müssen sich nicht in Gaming-Engines wie Unity einarbeiten.