WebVR Partea 5: Proiectare și Implementare
Publicat: 2022-03-11Îmi place să „termine” proiectele. Am ajuns la sfârșitul călătoriei noastre - și la nașterea simulării noastre gravitaționale cerești în WebVR.
În această postare finală, vom conecta codul nostru de simulare de înaltă performanță (articolele 1,2,3) într-un vizualizator WebVR bazat pe vizualizatorul canvas (articolul 4).
- Introducere și arhitectură „n-body problem”.
- Lucrătorii web ne oferă fire de navigare suplimentare
- WebAssembly și AssemblyScript pentru codul nostru de blocaj de performanță O(n²).
- Vizualizarea datelor Canvas
- Vizualizarea datelor WebVR
Acesta este un articol mai lung, așa că vom omite câteva detalii tehnice abordate anterior. Consultați postările anterioare dacă doriți o orientare sau citiți în mod periculos.
Am explorat schimbarea de paradigmă a browserului de la un runtime JavaScript cu un singur thread la un timp de rulare de înaltă performanță cu mai multe fire (lucrători web) (WebAssembly). Aceste caracteristici de computer desktop de performanță sunt disponibile în Progressive Web Apps și modelul de distribuție SaaS.
VR va crea medii de vânzări și marketing convingătoare, fără distragere a atenției, pentru a comunica, a convinge și a măsura implicarea (urmărirea ochilor și interacțiunea). Datele vor fi în continuare zero și unu, dar rezumatul executiv așteptat și experiența consumatorului vor fi WebVR - la fel cum construim astăzi experiențe de tablou de bord mobil pentru web-ul plat.
Aceste tehnologii permit, de asemenea, edge computing distribuit de browser. De exemplu, am putea crea o aplicație bazată pe web pentru a rula calculele noastre WebAssembly pentru milioane de stele într-o simulare. Un alt exemplu este o aplicație de animație care redă creațiile altor utilizatori în timp ce tu le editezi pe ale tale.
Conținutul de divertisment conduce la adoptarea realității virtuale, la fel ca divertismentul condus de pe mobil. Cu toate acestea, odată ce VR este normală (cum este astăzi designul mobile-first), va fi experiența așteptată (design VR-first). Acesta este un moment foarte interesant pentru a fi designer și dezvoltator - iar VR este o paradigmă de design complet diferită.
Nu ești un designer VR dacă nu poți prinde. Aceasta este o declarație îndrăzneață, iar astăzi este o scufundare profundă în designul VR. Acest domeniu este inventat pe măsură ce citiți asta. Scopul meu este să împărtășesc experiențele mele în software și film pentru a iniția conversația „VR-first design”. Învățăm cu toții unii de la alții.
Având în vedere aceste predicții grandioase, am vrut să finalizez acest proiect ca o demonstrație tehnologică profesională - WebVR este o alegere excelentă pentru asta!
WebVR și Google A-Frame
WebVR git repo este un furk al versiunii canvas din câteva motive. Face găzduirea proiectului pe paginile Github mai ușoară, iar WebVR a necesitat câteva modificări care ar fi aglomerat versiunea canvas și aceste articole.
Dacă vă amintiți prima noastră postare despre arhitectură, am delegat întreaga simulare către nBodySimulator
.
Postarea web worker a arătat că nBodySimulator
are o funcție step()
numită la fiecare 33ms din simulare. step()
apelează calculateForces()
pentru a rula codul nostru de simulare O(n²) WebAssembly (articolul 3), apoi actualizează pozițiile și revopsește. În postarea noastră anterioară despre crearea unei vizualizări canvas, am implementat acest lucru cu un element canvas, pornind de la această clasă de bază:
/** * Base class that console.log()s the simulation state. */ export class nBodyVisualizer { constructor(htmlElement) { this.htmlElement = htmlElement this.resize() this.scaleSize = 25 // divided into bodies drawSize. drawSize is log10(mass) // This could be refactored to the child class. // Art is never finished. It must be abandoned. } resize() {} paint(bodies) { console.log(JSON.stringify(bodies, null, 2)) } }
Definiți provocarea de integrare
Avem simularea. Acum, vrem să ne integrăm cu WebVR - fără a ne re-arhitecta proiectul. Orice ajustări pe care le facem simulării se întâmplă la fiecare 33 ms în firul principal de UI din funcția paint(bodies)
.
Acesta este modul în care vom măsura „terminat”. Sunt încântat - să trecem la treabă!
Cum să faci o realitate virtuală
În primul rând, avem nevoie de un design:
- Din ce este făcut VR?
- Cum este exprimat designul WebVR?
- Cum putem interacționa cu el?
Realitatea virtuală se întoarce în zorii timpului. Fiecare poveste despre foc de tabără este o lume virtuală minusculă de exagerări ciudate acoperite de detalii triviale.
Ne putem depăși de 10 ori povestea focului de tabără adăugând elemente vizuale și audio stereoscopice 3D. Instructorul meu de buget pentru producția de film obișnuia să spună: „Plătim doar pentru afiș. Nu construim realitatea.”
Dacă sunteți familiarizat cu browser-ul DOM, veți ști că creează o structură ierarhică arborescentă.
Implicit în designul web-ului este vizualizarea spectatorului din „față”. Privind din lateral, ar dezvălui elementele DOM ca linii, iar din spate, am vedea doar eticheta <body>
pentru că își întunecă copiii.
O parte a experienței captivante a VR permite utilizatorului să-și controleze punctul de vedere, stilul, ritmul și ordinea interacțiunilor. Nu trebuie să acorde atenție la nimic anume. Dacă mișcați sau rotiți camera în mod programat, acestea vor vomita literalmente din cauza bolii VR.
Vă rugăm să rețineți că boala VR nu este o glumă. Atât ochii, cât și urechile noastre interioare detectează mișcarea. Este foarte important pentru un animal care merge drept. Când acești senzori de mișcare nu sunt de acord, creierul nostru presupune în mod natural că gura noastră a mâncat din nou prostii și vomită. Toți am fost copii odată. S-au scris multe despre acest instinct de supraviețuire în VR deja. Titlul „Epic Fun” este gratuit pe Steam, iar rollercoaster-ul este cel mai bun demo VR sickness pe care l-am găsit.
Realitatea virtuală este exprimată ca un „grafic al scenei”. Un grafic al scenei are același model arborescent ca și DOM pentru a ascunde detaliile și complexitatea unui mediu 3D convingător. Cu toate acestea, în loc să derulăm și să direcționăm, poziționăm spectatorul acolo unde dorește să atragă experiența către el.
Iată graficul scenei Hello World din cadrul A-Frame WebVR de la Google:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, WebVR! • A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> </head> <body> <a-scene background="color: #FAFAFA"> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane> </a-scene> </body> </html>
Acest document HTML creează un DOM în browser. Etichetele <a-*>
fac parte din cadrul A-Frame, iar <a-scene>
este rădăcina graficului scenei. Aici, vedem patru primitive 3D afișate în scenă.
În primul rând, observați că vedem scena dintr-un browser web plat. Mica mască din dreapta jos invită utilizatorul să treacă la un mod stereoscopic 3D.
În teorie, ar trebui să fii capabil să:
- Deschide asta pe telefonul tău
- Ține telefonul la față
- Încântați-vă de splendoarea unei noi realități!
Nu am reușit niciodată să funcționeze fără lentilele elegante ale unei căști VR. Puteți obține o cască VR pentru un telefon Android la preț ieftin (un dispozitiv de bază bazat pe Google Cardboard), totuși, pentru dezvoltarea conținutului, vă sugerez un HMD (Head Mounted Display) autonom, cum ar fi Oculus Quest.
La fel ca scuba diving sau parașutism, Realitatea Virtuală este un sport cu echipament.
Învățarea designerilor VR „Cliff”
Observați că scena A-Frame Hello World are o iluminare și o cameră implicite:
- Fețele cubului au culori diferite - cubul se auto-umbră.
- Cubul aruncă o umbră în plan - există o lumină direcțională.
- Nu există niciun decalaj între cub și avion - aceasta este o lume cu gravitație.
Acestea sunt indicii esențiale care îi spun spectatorului: „Relaxează-te, acest lucru de pe fața ta este total normal”.
De asemenea, observați că această setare implicită este implicită în codul scenei Hello World de mai sus. A-Frame oferă cu înțelepciune o valoare implicită sensibilă, dar rețineți - camera și iluminarea sunt prăpastia pe care trebuie să o traverseze designerii de web plată pentru a crea VR.
Considerăm configurația implicită de iluminare de la sine înțeles. De exemplu, butoanele:
Observați cât de răspândită este această iluminare implicită în design și fotografie. Nici măcar butonul „design plat” nu a putut scăpa de iluminarea implicită a web-ului - aruncă o umbră în jos și în dreapta.
Proiectarea, comunicarea și implementarea setărilor de iluminare și camere sunt stânca de învățare a designerului WebVR. „Limba filmului” este o colecție de norme culturale - exprimate ca diferite configurații de cameră și iluminare - care comunică emoțional povestea publicului. Profesioniștii în film care proiectează/mută luminile și camera în jurul unei scene sunt departamentul de prindere.
Înapoi la realitatea noastră virtuală
Acum, să ne întoarcem la muncă. Scena noastră WebVR cerească are un model similar:
<!DOCTYPE> <html> <head> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script> <script src="main.js"></script> </head> <body> <a-scene> <a-sky color="#222"></a-sky> <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity> <a-entity></a-entity> <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!..."> </a-entity> <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity> </a-scene> </body> </html>
Acest document HTML încarcă cadrul A-Frame și un plugin de interacțiune. Scena noastră începe la <a-scene>
.
În interior, începem cu un element <a-sky color="#222"></a-sky>
pentru a colora pe fundal tot ceea ce nu definim în scenă.
Apoi, creăm un „plan orbital” pe care spectatorul să-l „țină” în timp ce zboară prin lumea noastră ciudată și necunoscută. Creăm acest lucru ca un disc și o mică sferă neagră la (0,0,0). Fără asta, întoarcerea mi s-a părut „nefondată”:
<a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity>
În continuare, definim o colecție în care putem adăuga/elimina/repoziționa entități A-Frame.
<a-entity></a-entity>
Aceasta este clarificarea paint(bodies)
nBodyVisualizer
pentru a-și face treaba.
Apoi, creăm relația dintre privitor și această lume. Ca demonstrație tehnologică, scopul acestei lumi este de a permite spectatorului să exploreze WebVR și tehnologia browserului care o permite. O narațiune simplă „astronaut” creează un sentiment de joc, iar acest indicator stelar este un alt punct de referință pentru navigație.
<a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!\n ..."> </a-entity>
Asta completează graficul scenei noastre. În cele din urmă, am vrut un fel de interacțiune pe o demonstrație de telefon între utilizator și această lume spinnoasă. Cum putem recrea butonul „Aruncă resturi” în VR?
Butonul este un element primordial al designului modern - unde sunt butoanele VR?
Interacțiuni în WebVR
Realitatea virtuală are propriile sale „de sus” și „dedesubt”. Prima interacțiune a unui spectator este prin intermediul avatarului sau al camerei. Acestea sunt toate comenzile pentru a mări.
Dacă citiți acest lucru pe un desktop, puteți WASD pentru a muta și mouse-ul pentru a roti camera. Această explorare dezvăluie informații, dar nu îți exprimă voința.
Real Reality are câteva caracteristici foarte importante care nu se găsesc adesea pe web:
- Perspectivă - obiectele devin vizibil mai mici pe măsură ce se îndepărtează de noi.
- Ocluzie - obiectele sunt ascunse și dezvăluite în funcție de poziție.
VR simulează aceste caracteristici pentru a crea efectul 3D. Ele pot fi, de asemenea, folosite în VR pentru a dezvălui informații și interfață - și pentru a stabili starea de spirit înainte de a prezenta interacțiunile. Am descoperit că majoritatea oamenilor au nevoie doar de un minut pentru a se bucura de experiență înainte de a merge mai departe.

În WebVR, interacționăm în spațiul 3D. Avem două instrumente de bază pentru aceasta:
- Coliziune - un eveniment 3D pasiv declanșat atunci când două obiecte împart același spațiu.
- Proiecție - un apel de funcție 2D activ care listează toate obiectele care intersectează o linie.
Coliziunea este cea mai „asemănătoare VR” interacțiune
În VR, o „coliziune” este exact ceea ce sună: când două obiecte împart același spațiu, A-Frame creează un eveniment.
Pentru ca utilizatorul să „apăseze” un buton, trebuie să îi dăm un pion și ceva cu care să apese butonul.
Din păcate, WebVR nu își poate asuma încă controlerele - mulți oameni se vor uita la o versiune flat-web pe desktop sau pe telefon și mulți vor folosi un set de căști precum Google Cardboard sau Gear VR de la Samsung pentru a afișa o versiune stereoscopică.
Dacă utilizatorul nu are controlere, nu poate atinge și „atinge” lucrurile, așa că orice coliziune va trebui să aibă loc cu „spațiul personal”.
Am putea oferi jucătorului un pion în formă de astronaut pentru a se deplasa, dar forțarea utilizatorului într-o miasmă învolburată de planete pare puțin dezamăgitoare și contrară spațiului designului nostru.
Proiecția este un clic 2D „asemănător unui web” într-un spațiu 3D
Pe lângă „coliziune”, putem folosi și „proiecție”. Putem proiecta o linie prin scena noastră și să vedem ce atinge. Cel mai comun exemplu este „raza de teleport”.
O rază de teleportare trasează o linie în lume pentru a arăta unde se poate mișca un jucător. Această „proiecție” caută locuri de aterizare. Returnează unul sau mai multe obiecte în calea proiecției. Iată un exemplu de rază de teleportare:
Observați că raza este de fapt implementată ca o parabolă îndreptată în jos. Aceasta înseamnă că se intersectează în mod natural cu „pământul” ca un obiect aruncat. Acest lucru stabilește, de asemenea, o distanță maximă de teleportare. Limitele sunt cele mai importante alegeri de design în VR. Din fericire, realitatea are multe limitări naturale.
Proiecția „aplatizează” lumea 3D în 2D, astfel încât să puteți îndrepta spre lucruri pentru a face clic pe el ca pe un mouse. Împuşcăturile la persoana întâi sunt jocuri elaborate de „clic 2D” pe butoane extrem de frustrante – adesea cu o poveste elaborată pentru a explica de ce nu este în regulă acele butoane blestemate vă „dau clic” înapoi.
Există atât de multe arme în VR, deoarece armele au fost perfecționate ca șoareci 3D precisi și de încredere - iar consumatorii știu să facă clic fără să învețe.
Proiectia ofera si siguranta distantei in relatia cu scena. Amintiți-vă, apropierea de ceva în VR va bloca în mod natural toate celelalte lucruri a căror importanță poate să nu fi fost încă dezvăluită.
Proiecție fără controlere folosind „Privirea”
Pentru a crea această interacțiune primitivă în WebVR fără controlere, putem proiecta „privirea” spectatorilor ca un „cursor” de linie de vedere. Acest cursor poate fi folosit programatic pentru a interacționa cu obiecte cu o „siguranță”. Acest lucru este comunicat privitorului ca un mic cerc albastru. Acum facem clic!
Dacă vă amintiți poveștile despre foc de tabără, cu cât este mai mare minciuna, cu atât sunt necesare mai puține detalii pentru a o vinde. O interacțiune „privire” evidentă și absurdă este să te uiți la soare. Folosim această „privire” pentru a declanșa adăugarea de noi planete „de resturi” la simularea noastră. Niciun spectator nu a pus la îndoială această alegere - VR este destul de fermecător atunci când absurd.
În A-Frame, exprimăm camera (pionul invizibil al jucătorilor) și acest „cursor” de linie vizuală ca dispozitivul camerei noastre. Plasarea <a-cursor>
în interiorul <a-camera>
face ca transformările camerei să fie aplicate și la cursor. Când jucătorul își mișcă/rotește pionul ( a-camera
), acesta își mișcă/rotește și privirea ( a-cursor
).
// src/index.html <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity>
„Siguranța” cursorului așteaptă până când a trecut o secundă întreagă de „privire” înainte de a emite un eveniment.
Am folosit iluminarea implicită, așa că este posibil să observați că există un „spate” neluminat al soarelui. Deși nu am fost în afara planului orbital, nu cred că așa funcționează soarele. Cu toate acestea, funcționează pentru posterul nostru demo-tehnologic al realității.
O variantă alternativă ar fi să puneți iluminarea în interiorul elementului camerei, astfel încât să se miște cu utilizatorul. Acest lucru ar crea o experiență mai intimă - și posibil înfricoșătoare - miner de asteroizi. Acestea sunt alegeri de design distractive.
Avem un plan de integrare
Cu asta, avem acum punctele noastre de integrare între A-Frame <a-scene>
și simularea noastră JavaScript:
A-Frame <a-scene>
:
O colecție numită pentru corpuri:
<a-entity></a-entity>
Un cursor care va emite evenimente de proiecție:
<a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>
Simularea noastră JavaScript:
nBodyVisWebVR.paint(bodies)
- adăugați/eliminați/repoziționați entitățile VR din corpurile de simulareaddBodyArgs(name, color, x, y, z, mass, vX, vY, vZ)
pentru a adăuga noi corpuri de resturi la simulare
index.html
încarcă main.js
, care inițializează simularea noastră la fel ca versiunea canvas:
// src/main.js import { nBodyVisualizer, nBodyVisWebVR } from ."/nBodyVisualizer" import { Body, nBodySimulator } from ."/nBodySimulator" window.onload = function() { // Create a Simulation const sim = new nBodySimulator() // this Visualizer manages the UI sim.addVisualization(new nBodyVisWebVR(document.getElementById("a-bodies"), sim)) // making up stable universes is hard // name color xyzm vz vy vz sim.addBody(new Body("star", "yellow", 0, 0, 1, 1e9)) sim.addBody(new Body("hot-jupiter", "red", -1, -1, 1, 1e4, .24, -0.05, 0)) sim.addBody(new Body("cold-jupiter", "purple", 4, 4, .5, 1e4, -.07, 0.04, 0)) // Start simulation sim.start() // Add another sim.addBody(new Body("saturn", "blue", -8, -8, .1, 1e3, .07, -.035, 0)) }
Veți observa că aici am setat elementul htmlElement
al vizualizatorului la colecția a a-bodies
pentru a păstra corpurile.
Gestionarea programatică a obiectelor A-Frame din JavaScript
După ce ne-am declarat scena în index.html
, acum suntem gata să codificăm vizualizatorul.
Mai întâi, am configurat nBodyVisualizer
pentru a citi din lista de corpuri nBodySimulation
și a crea/actualiza/șterge obiecte A-Frame din colecția <a-entity></a-entity>
.
// src/nBodyVisualizer.js /** * This is the WebVR visualizer. * It's responsible for painting and setting up the entire scene. */ export class nBodyVisWebVR extends nBodyVisualizer { constructor(htmlElement, sim) { // HTML Element is a-collection#a-bodies. super(htmlElement) // We add these to the global namespace because // this isn't the core problem we are trying to solve. window.sim = sim this.nextId = 0 } resize() {}
În constructor, salvăm colecția noastră A-Frame, setăm o variabilă globală pentru evenimentul nostru privire pentru a găsi simularea și inițializam un contor de id pe care îl vom folosi pentru a potrivi corpurile dintre simularea noastră și scena A-Frame.
paint(bodies) { let i // Create lookup table: lookup[body.aframeId] = body const lookup = bodies.reduce( (total, body) => { // If new body, give it an aframeId if (!body.aframeId) body.aframeId = `a-sim-body-${body.name}-${this.nextId++}` total[body.aframeId] = body return total }, {}) // Loop through existing a-sim-bodies and remove any that are not in // the lookup - this is our dropped debris const aSimBodies = document.querySelectorAll(."a-sim-body") for (i = 0; i < aSimBodies.length; i++) { if (!lookup[aSimBodies[i].id]) { // if we don't find the scene's a-body in the lookup table of Body()s, // remove the a-body from the scene aSimBodies[i].parentNode.removeChild(aSimBodies[i]); } } // loop through sim bodies and upsert let aBody bodies.forEach( body => { // Find the html element for this aframeId aBody = document.getElementById(body.aframeId) // If html element not found, make one. if (!aBody) { this.htmlElement.innerHTML += ` <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>` aBody = document.getElementById(body.aframeId) } // reposition aBody.object3D.position.set(body.x, body.y, body.z) }) }
În primul rând, parcurgem corpurile sim pentru a eticheta și/sau a crea un tabel de căutare pentru potrivirea entităților A-Frame cu corpurile de simulare.
Apoi, parcurgem corpurile A-Frame existente și le eliminăm pe cele care au fost tăiate de simulare pentru a călători în afara limitelor. Acest lucru crește performanța percepută a experienței.
În cele din urmă, parcurgem corpurile sim pentru a crea o nouă <a-sphere>
pentru corpurile lipsă și pentru a le repoziționa pe celelalte cu aBody.object3D.position.set(body.x, body.y, body.z)
Putem modifica în mod programatic elementele din scena A-Frame folosind funcții DOM standard. Pentru a adăuga un element la scenă, adăugăm un șir la HTML-ul interior al containerului. Acest cod îmi pare ciudat, dar funcționează și nu am găsit nimic mai bun.
Veți observa când creăm șirul de atașat, avem un operator ternar lângă „stea” pentru a seta un atribut.
<a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>`
Dacă corpul este o „stea”, adăugăm câteva atribute suplimentare care descriu evenimentele sale. Iată cum arată steaua noastră când este montată în DOM:
<a-sphere class="a-sim-body" dynamic-body="" debris-listener="" event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" position="0 0 0" radius="0.36" color="yellow" material="" geometry=""></a-sphere>
Trei atribute, debris-listener
, event-set__enter
și event-set__leave
, stabilesc interacțiunile noastre și reprezintă ultima tură a integrării noastre.
Definirea evenimentelor și interacțiunilor A-Frame
Folosim pachetul NPM „aframe-event-set-component” în atributele entității pentru a schimba culoarea soarelui atunci când privitorul „se uită” la el.
Această „privire” este o proiecție din poziția și rotația privitorului, iar interacțiunea oferă feedback-ul necesar că privirea lui face ceva.
Sfera noastră stelară are acum două evenimente scurte activate de plugin, event-set__enter
și event-set__leave
:
<a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere>
Apoi, decoram sfera noastră stelară cu un debris-listener
care îl vom implementa ca componentă A-Frame personalizată.
<a-sphere ... debris-listener="" … ></a-sphere>
Componentele A-Frame sunt definite la nivel global:
// src/nBodyVisualizer.js // Component to add new bodies when the user stares at the sun. See HTML AFRAME.registerComponent('debris-listener', { init: function () { // Helper function function rando(scale) { return (Math.random()-.5) * scale } // Add 10 new bodies this.el.addEventListener('click', function (evt) { for (let x=0; x<10; x++) { // name, color, x, y, z, mass, vx, vy, vz window.sim.addBodyArgs("debris", "white", rando(10), rando(10), rando(10), 1, rando(.1), rando(.1), rando(.1)) } }) } })
Această componentă A-Frame acționează ca un ascultător „clic” care poate fi declanșat de cursorul privirii pentru a adăuga 10 noi corpuri aleatorii scenei noastre.
A rezuma:
- Declaram scena WebVR cu A-Frame in HTML standard.
- Putem adăuga/elimina/actualiza programatic entități A-Frame în scenă din JavaScript.
- Putem crea interacțiuni în JavaScript cu handlere de evenimente prin plugin-uri și componente A-Frame.
WebVR: Veni, Vidi, Vici
Sper că ați obținut la fel de mult din această demonstrație tehnologică ca și mine. Acolo unde am aplicat aceste funcții (lucrători web și WebAssembly) la WebVR, ele pot fi aplicate și la computerul de margine a browserului.
Un val tehnologic uriaș a sosit - Realitatea Virtuală (VR). Indiferent de ce ai simțit prima dată când ai ținut un smartphone, experimentarea VR pentru prima dată oferă o experiență emoțională de 10 ori în fiecare aspect al computerului. Au trecut doar 12 ani de la primul iPhone.
VR există de mult mai mult timp, dar tehnologia necesară pentru a aduce VR la utilizatorii obișnuiți a ajuns prin intermediul revoluției mobile și al Oculus Quest de la Facebook - nu prin revoluția PC-ului.
Internetul și open-source sunt printre cele mai mari minuni ale omenirii din lume. Tuturor oamenilor care au creat internetul plat - ridic un toast pentru curajul și simțul tău de aventură.
Manifest! Vom construi lumi, pentru că avem puterea de a crea.