CS185c
Chris Pollett
Feb 6, 2019
Using Sky, Camera, Cursor, Link
<!DOCTYPE html> <html> <head> <title>Sky Camera Controls</title> <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script> </head> <body> <a-scene> <a-assets> <img id="city" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/city.jpg"> <img id="city-thumb" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/thumb-city.jpg"> </a-assets>; <!-- 360-degree image. --> <a-sky id="image-360" radius="10" src="#city"></a-sky> <!-- Image links. --> <a-link class="link" href="hello.html" title="Hello Page" on="click" position="0 -1 -4"></a-link> <!-- Camera + cursor. --> <a-entity camera look-controls> <a-cursor id="cursor" animation__click="property: scale; startEvents: click; from: 0.1 0.1 0.1; to: 1 1 1; dur: 150" animation__fusing="property: fusing; startEvents: fusing; from: 1 1 1; to: 0.1 0.1 0.1; dur: 1500" fuse="true" raycaster="objects: .link"> </a-cursor> </a-entity> </a-scene> </body> </html>
<a-entity camera="active: true" look-controls wasd-controls position="0 0 0" data-aframe-default-camera></a-entity>
var secondCameraEl = document.querySelector('#second-camera'); secondCameraEl.setAttribute('camera', 'active', true);
Below is an A-frame example in which we use three clickable planes with images on them to control what the sky looks like.
It pretty much comes from the A-Frame site, but where I modified the included libraries so that it works with the Oculus Go.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>360° Image Gallery</title> <meta name="description" content="360° Image Gallery - A-Frame"> <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script> <script onkeyup="" src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js" ></script> <script src="https://unpkg.com/aframe-event-set-component/dist/aframe-event-set-component.min.js"></script> <script src="https://unpkg.com/aframe-layout-component/dist/aframe-layout-component.min.js"></script> <script src="https://unpkg.com/aframe-template-component/dist/aframe-template-component.min.js"></script> </head> <body> <a-scene> <a-assets> <img id="city" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/city.jpg"> <img id="city-thumb" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/thumb-city.jpg"> <img id="cubes-thumb" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/thumb-cubes.jpg"> <img id="sechelt-thumb" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/thumb-sechelt.jpg"> <audio id="click-sound" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/audio/click.ogg"></audio> <img id="cubes" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/cubes.jpg"> <img id="sechelt" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg"> <!-- Image link template to be reused. --> <script id="link" type="text/html"> <a-entity class="link" geometry="primitive: plane; height: 1; width: 1" material="shader: flat; src: ${thumb}" event-set__1="_event: mousedown; scale: 1 1 1" event-set__2="_event: mouseup; scale: 1.2 1.2 1" event-set__3="_event: mouseenter; scale: 1.2 1.2 1" event-set__4="_event: mouseleave; scale: 1 1 1" event-set__5="_event: click; _target: #image-360; src: ${src}" > </a-entity> </script> </a-assets> <!-- 360-degree image. --> <a-sky id="image-360" radius="10" src="#city"></a-sky> <!-- Image links. --> <a-entity id="links" layout="type: line; margin: 1.5" position="0 1 -4"> <a-entity position="-2 0 0" template="src: #link" data-src="#cubes" data-thumb="#cubes-thumb" sound="on: click; src: #click-sound"></a-entity> <a-entity position="-2 0 0" template="src: #link" data-src="#city" data-thumb="#city-thumb" sound="on: click; src: #click-sound"></a-entity> <a-entity position="2 0 0" template="src: #link" data-src="#sechelt" data-thumb="#sechelt-thumb" sound="on: click; src: #click-sound"></a-entity> </a-entity> <!-- Camera + cursor. --> <a-entity camera look-controls> <a-cursor id="cursor" animation__click="property: scale; startEvents: click; from: 0.1 0.1 0.1; to: 1 1 1; dur: 150" animation__fusing="property: fusing; startEvents: fusing; from: 1 1 1; to: 0.1 0.1 0.1; dur: 1500" event-set__1="_event: mouseenter; color: springgreen" event-set__2="_event: mouseleave; color: black " fuse="true" raycaster="objects: .link"> </a-cursor> </a-entity> </a-scene> </body> </html>
event-set__${id}="_event: ${eventName}; ${someProperty}: ${toValue}"
var extendDeep = AFRAME.utils.extendDeep; // The mesh mixin provides common material properties // for creating mesh-based primitives. // This makes the material component a default component // and maps all the base material properties. var meshMixin = AFRAME.primitives.getMeshMixin(); AFRAME.registerPrimitive('a-box', extendDeep({}, meshMixin, { // Preset default components. These components and component //properties will be attached to the entity out-of-the-box. defaultComponents: { geometry: {primitive: 'box'} }, // Defined mappings from HTML attributes to component properties (using dots as delimiters). // If we set `depth="5"` in HTML, then the primitive will automatically set `geometry="depth: 5"`. mappings: { depth: 'geometry.depth', height: 'geometry.height', width: 'geometry.width' } }));
AFRAME.registerComponent('foo', { schema: {/* properties on component*/}, init: function () {/* when instatiated*/}, update: function () {/* when schema changed*/}, tick: function () {/* called during render loop */}, remove: function () {/* if delete */}, pause: function () {/* if no longer rendering*/}, play: function () {/*if resume */} });
Using the previous slide we can abstract the control processes going on between the Brain, Sense Organ, and the Environment, or between the VR System, Brain, Sense Organ, and the Environment: