---
### 20 Minutes into the Future with
## Google Cardboard
### and JavaScript
---
# Hello
## I'm Max Glenister
### @omgmog on the Internet
---

## SusHack
### 2013 — 2015
---

#### Pretty cool.
---

## The Future
### 2015 — ?
---
### In your pocket is a VR device.
---

---
### Most phones contain a lot of sensors...
---
## Camera
---
## Touch Screen
---
## GPS
---
## WiFi
---
## Microphone
---
## Ambient Light Sensor
---
## Accelerometer
---
## Magnetometer
---
## Gyroscope
---
## ...
---

---
### How can we use this for VR?
---

---

---

---
- Geolocation
- Device Orientation
- Fullscreen
- getUserMedia
- Web Audio
- WebGL
---

### Geolocation
---
``` javascript
navigator.geolocation.getCurrentPosition(function (pos) {
console.log(pos.coords.latitude);
console.log(pos.coords.longitude);
});
```
---
---

---

### Device Orientation
---
#### Rotation on X-axis
_Pitch_ or _Beta_ (β) range of -180° to 180°
---
#### Rotation on Y-axis
_Roll_ or _Gamma_ (γ) range of -90° to 90°
---
#### Rotation on Z-axis
_Yaw_ or _Alpha_ (α) range of 0° to 360°
---
``` javascript
window.addEventListener('deviceorientation',
function (e) {
console.log(e.gamma);
console.log(e.beta);
console.log(e.alpha);
},
false
);
```
---

### Fullscreen
---

---
``` javascript
var button = document.querySelector('button');
button.addEventListener('click',
function (e) {
document.body.requestFullScreen();
}
);
```
---

### getUserMedia
---
``` javascript
navigator.getUserMedia(
// Constraints
{ video: true, audio: false },
// Success function
function (stream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(stream);
video.onloadedmetadata = function(e) {
// Stream loaded, do some stuff
};
},
// Error function
function (err) {
console.log(err);
}
);
```
---
---

### Web Audio
---
``` javascript
// Set up the audio context
var context = new AudioContext();
// Create an oscillator
var oscillator = context.createOscillator();
// Connect the oscillator to our playback device
oscillator.connect(context.destination);
// Start the sound output
oscillator.start();
```
---
---
``` javascript
var context = new AudioContext();
var file = 'demo.wav';
var request = new XMLHttpRequest();
var source;
request.open('GET', file, true);
request.responseType = 'arraybuffer';
request.onload = function () {
source = context.createBufferSource();
context.decodeAudioData(request.response, function (buffer) {
source.buffer = buffer;
source.connect(context.destination);
source.start(context.currentTime);
});
};
request.send();
```
---
---

### WebGL
---

### WebGL
---

### WebGL (with three.js)
---
## This bit is really simple!
---
``` javascript
// Set it all up...
var width = 600, height = 300, aspect = width/height;
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer({
alpha: true, antialias: true, logarithmicDepthBuffer: true
});
renderer.setSize( width, height );
document.body.appendChild(renderer.domElement);
// ... Continued
```
---
``` javascript
// Create a cube...
var cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
var cubeMaterial = new THREE.MeshBasicMaterial({color: 0x000000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
scene.add(cube);
// Add some edges...
var cubeEdges = new THREE.EdgesHelper(cube, 0xff0000);
cubeEdges.material.linewidth = 5;
scene.add(cubeEdges);
// ... Continued
```
---
``` javascript
// Lights...
var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 6, 40);
pointLight.lookAt(cube.position);
scene.add(pointLight);
// Camera...
var camera = new T.PerspectiveCamera(35, aspect, 1, 1000);
camera.position.set(20, 20, 20);
camera.lookAt(scene.position);
// ... Continued
```
---
``` javascript
// Action!
function render() {
cube.rotation.x += 0.04;
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
```
---
---
---
### Making it work in 3D
---
``` javascript
// Include the StereoEffect.js file
// After setting up your renderer
effect = new THREE.StereoEffect(renderer);
effect.eyeSeparation = 1; // Set the IPD
effect.setSize( width, height );
// Instead of calling renderer.render(scene, camera)
effect.render(scene, camera)
```
---
---
## INFORMATION
OVERLOAD
---

---

---

### Google Cardboard
---

---

---

---
---
## Some demos
---
---
### These are all available online
## [blog.omgmog.net/jscard.xyz](https://blog.omgmog.net/jscard.xyz)
---
## Lastly...
---
### Consider UX
I've made a list of resources...
[github.com/omgmog/ui-ux-vr](https://github.com/omgmog/ui-ux-vr)
---
## I've been Max Glenister
# Thanks