geildanke.com @fischaelameer MICHAELA LEHR Founder · Geil,Danke! · Frontend Developer, UX Designer @fischaelameer Goodbye, Flatland! An introduction to React VR and what it means for web developers
geildanke.com @fischaelameer You should care about WebVR.
geildanke.com @fischaelameer VR Concepts
geildanke.com @fischaelameer VR Concepts ReactVR
geildanke.com @fischaelameer VR Concepts ReactVR UX Design & VR
geildanke.com @fischaelameer Virtual Reality is tricking our eyes and brain to think of a 2D image to be in 3D.
geildanke.com @fischaelameer Virtual Reality changes the 
 way we relate to technology.
geildanke.com @fischaelameer Virtual Reality Concepts
geildanke.com @fischaelameer Stereoscopic Images
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer IPD – Interpupillary distance
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer Tracking
geildanke.com @fischaelameer
geildanke.com @fischaelameer Rotation
geildanke.com @fischaelameer Rotation Position
geildanke.com @fischaelameer
geildanke.com @fischaelameer Rotation Position
geildanke.com @fischaelameer Browser https://github.com/mrdoob/three.js
geildanke.com @fischaelameer Browser WebGL https://github.com/mrdoob/three.js
geildanke.com @fischaelameer Browser WebVRWebGL https://github.com/mrdoob/three.js
geildanke.com @fischaelameer Browser WebVRWebGL https://github.com/mrdoob/three.js three.js Ricardo Cabello
geildanke.com @fischaelameer Browser WebVRWebGL https://facebookincubator.github.io/react-vr/index.html three.js ReactVR
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer x: 0, y: 0, z: 0
geildanke.com @fischaelameer x: 0, y: 0, z: 0
geildanke.com @fischaelameer
geildanke.com @fischaelameer npm install -g react-vr-cli react-vr init GEILDANKE_REACTVR_PANO cd GEILDANKE_REACTVR_PANORAMA npm start
geildanke.com @fischaelameer /GEILDANKE_REACTVR_PANO !"" index.vr.js !"" node_modules !"" package.json !"" postinstall.js !"" rn-cli.config.js !"" static_assets #   %"" vr-mountain.jpg %"" vr !"" client.js %"" index.html
geildanke.com @fischaelameer import React from 'react'; import { AppRegistry, asset, Pano, View } from 'react-vr'; class GEILDANKE_REACTVR_PANO extends React.Component { render() { return ( <View> <Pano source = { asset('vr-mountain.jpg') }/> </View> ); } }; AppRegistry.registerComponent('GEILDANKE_REACTVR_PANO', () => GEILDANKE_REACTVR_PANO); index.vr.js
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer It was the pioneer days; people had to make their own interrogation rooms. Out of cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,' it's not because I want you or because I can't have you. It's my estimation that every man ever got a statue made of him was one kind of sommbitch or another. Oh my god you will never believe what happened at school today. From beneath you, it devours. I am never gonna see a merman, ever. It was supposed to confuse him, but it just made him peppy. It was like the Heimlich, with stripes! How did your brain even learn human speech? I'm just so curious. Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's ludicrous to have these interlocking bodies and not...interlock. I just don't see why everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky world that still makes sense to me. You are talking crazy-person talk. http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @fischaelameer It was the pioneer days; people had to make their own interrogation rooms. Out of cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,' it's not because I want you or because I can't have you. It's my estimation that every man ever got a statue made of him was one kind of sommbitch or another. Oh my god you will never believe what happened at school today. From beneath you, it devours. I am never gonna see a merman, ever. It was supposed to confuse him, but it just made him peppy. It was like the Heimlich, with stripes! How did your brain even learn human speech? I'm just so curious. Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's ludicrous to have these interlocking bodies and not...interlock. I just don't see why everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky world that still makes sense to me. You are talking crazy-person talk. http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer Goodbye, UX metaphors!
geildanke.com @fischaelameer Goodbye, UX metaphors!
geildanke.com @fischaelameer Goodbye, UX metaphors!
geildanke.com @fischaelameer Lightning UI Button GalleryImages GalleryImage Room Wall index.vr.js
geildanke.com @fischaelameer import React from 'react'; import { AppRegistry, asset, View } from 'react-vr'; import Images from './Images'; import Lightning from './Lightning'; import Room from './Room'; import UI from './UI'; import World from './World'; class GEILDANKE_REACTVR_GALLERY extends React.Component { render() { return ( <View> <Lightning /> <World /> <Room /> <Images /> <UI /> </View> ); } }; AppRegistry.registerComponent('GEILDANKE_REACTVR_GALLERY', () => GEILDANKE_REACTVR_GALLERY); index.vr.js
geildanke.com @fischaelameer import React from 'react'; import { AmbientLight, PointLight, View } from 'react-vr'; class Lightning extends React.Component { render() { return( <View> <AmbientLight intensity = { 1.2 } /> <PointLight intensity = { 0.25 } style = {{ color: '#ffffff', transform: [{ translate : [ 0, 4, 0.25 ] }] }} /> </View> ); } } module.exports = Lightning; Lightning.js
geildanke.com @fischaelameer import React from 'react'; import { AmbientLight, PointLight, View } from 'react-vr'; class Lightning extends React.Component { render() { return( <View> <AmbientLight intensity = { 1.2 } /> <PointLight intensity = { 0.25 } style = {{ color: '#ffffff', transform: [{ translate : [ 0, 4, 0.25 ] }] }} /> </View> ); } } module.exports = Lightning; Lightning.js
geildanke.com @fischaelameer import React from 'react'; import { AmbientLight, PointLight, View } from 'react-vr'; class Lightning extends React.Component { render() { return( <View> <AmbientLight intensity = { 1.2 } /> <PointLight intensity = { 0.25 } style = {{ color: '#ffffff', transform: [{ translate : [ 0, 4, 0.25 ] }] }} /> </View> ); } } module.exports = Lightning; Lightning.js
geildanke.com @fischaelameer … render() { let scale = this.props.scale, translate = this.props.translate, wall = null, wallMat = {mesh:asset('wall.obj'), mtl:asset('wall.mtl'), lit: true}, windowMat = {mesh:asset('window.obj'), mtl:asset('window.mtl'), lit: true}; if (this.props.hasWindow && this.props.hasWindow === true) { wall = <Mesh style={{transform: [{translate: translate}, {scale: scale},],}} source={windowMat} />; } else { wall = <Mesh style={{transform: [{translate: translate}, {scale: scale},],}} source={wallMat} />; } return ( wall ); } … Wall.js
geildanke.com @fischaelameer … import Wall from './Wall'; class Room extends React.Component { render() { return( <View> <Wall scale={[5, 0.2, 10]} translate={[0, -2.9, -5.02]} /> <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> <Wall hasWindow scale={[5, 3, 0.02]} translate={[0, 0, 4.98]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[-5.02, 0, -5.02]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[5.02, 0, -5.02]} /> </View> ); } } … Room.js
geildanke.com @fischaelameer … import Wall from './Wall'; class Room extends React.Component { render() { return( <View> <Wall scale={[5, 0.2, 10]} translate={[0, -2.9, -5.02]} /> <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> <Wall hasWindow scale={[5, 3, 0.02]} translate={[0, 0, 4.98]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[-5.02, 0, -5.02]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[5.02, 0, -5.02]} /> </View> ); } } … <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> Room.js
geildanke.com @fischaelameer … import Wall from './Wall'; class Room extends React.Component { render() { return( <View> <Wall scale={[5, 0.2, 10]} translate={[0, -2.9, -5.02]} /> <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> <Wall hasWindow scale={[5, 3, 0.02]} translate={[0, 0, 4.98]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[-5.02, 0, -5.02]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[5.02, 0, -5.02]} /> </View> ); } } … <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> Room.js
geildanke.com @fischaelameer … import Wall from './Wall'; class Room extends React.Component { render() { return( <View> <Wall scale={[5, 0.2, 10]} translate={[0, -2.9, -5.02]} /> <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> <Wall hasWindow scale={[5, 3, 0.02]} translate={[0, 0, 4.98]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[-5.02, 0, -5.02]} /> <Wall hasWindow scale={[0.02, 3, 10]} translate={[5.02, 0, -5.02]} /> </View> ); } } … <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} /> Room.js
geildanke.com @fischaelameer x <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} />
geildanke.com @fischaelameer y x <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} />
geildanke.com @fischaelameer y x z <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} />
geildanke.com @fischaelameer y x z <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} />
geildanke.com @fischaelameer y x z 1 unit = 1 meter 1 1 1 <Wall scale={[5, 3, 0.2]} translate={[0, 0, -5]} />
geildanke.com @fischaelameer 3D Coordinate System, Units & Scaling Flexbox Layout Animations (Animated API) React VR Components
geildanke.com @fischaelameer 3D Coordinate System, Units & Scaling Flexbox Layout Animations (Animated API) React VR Components
geildanke.com @fischaelameer … let texture = this.props.texture, imageWidth = this.props.width; <Image style={{ margin: 0.05, width: imageWidth, height: imageWidth, }} source={texture} /> … GalleryImage.js
geildanke.com @fischaelameer … for (let i = 0; i < iMax; i += 1) { images.push( <GalleryImage key={i} texture={config[i].texture} index={i} length={this.numberOfImages} width={this.imageWidth} /> ); } … GalleryImages.js
geildanke.com @fischaelameer … for (let i = 0; i < iMax; i += 1) { images.push( <GalleryImage key={i} texture={config[i].texture} index={i} length={this.numberOfImages} width={this.imageWidth} /> ); } … … <View> {images} </View> … GalleryImages.js
geildanke.com @fischaelameer … for (let i = 0; i < iMax; i += 1) { images.push( <GalleryImage key={i} texture={config[i].texture} index={i} length={this.numberOfImages} width={this.imageWidth} /> ); } … … <View style={{ flexDirection: 'row', }} > {images} </View> … GalleryImages.js
geildanke.com @fischaelameer
geildanke.com @fischaelameer 3D Coordinate System, Units & Scaling Flexbox Layout Animations (Animated API) React VR Components
geildanke.com @fischaelameer 3D Coordinate System, Units & Scaling Flexbox Layout Animations (Animated API) React VR Components
geildanke.com @fischaelameer GalleryImages.js … class GalleryImages extends React.Component { constructor(props) { super(); this.state = { scrollValue: new Animated.Value(0), }; } componentWillMount() { Animated.timing( this.state.scrollValue, { toValue: 60, duration: 2000, easing: Easing.linear, } ).start(); } …
geildanke.com @fischaelameer GalleryImages.js … class GalleryImages extends React.Component { constructor(props) { super(); this.state = { scrollValue: new Animated.Value(0), }; } componentWillMount() { Animated.timing( this.state.scrollValue, { toValue: 60, duration: 2000, easing: Easing.linear, } ).start(); } … … <Animated.View style={{ flexDirection: 'row', transform: [ {translateX: this.state.scrollValue}, ], }} > {images} </Animated.View> …
geildanke.com @fischaelameer 3D Coordinate System, Units & Scaling Flexbox Layout Animations (Animated API) React VR Components
geildanke.com @fischaelameer View Image Core Components Pano Mesh React VR Components AmbientLight, PointLight,
geildanke.com @fischaelameer View Image Text Core Components Pano Mesh React VR Components AmbientLight, PointLight,
geildanke.com @fischaelameer View Image Text Core Components Pano Mesh React VR Components AmbientLight, PointLight, DirectionalLight, SpotLight
geildanke.com @fischaelameer View Image Text Core Components Pano Mesh React VR Components VrButton AmbientLight, PointLight, DirectionalLight, SpotLight
geildanke.com @fischaelameer View Image Text Core Components Pano Mesh React VR Components VrButton AmbientLight, PointLight, DirectionalLight, SpotLight Sound
geildanke.com @fischaelameer UX Design for VR
geildanke.com @fischaelameer Comfort Interpretability Usefulness Delight Beau Cronin https://medium.com/@beaucronin/the-hierarchy-of-needs-in-virtual-reality-development-4333a4833acc
geildanke.com @fischaelameer Presence Comfort Interpretability Usefulness Delight Beau Cronin https://medium.com/@beaucronin/the-hierarchy-of-needs-in-virtual-reality-development-4333a4833acc
geildanke.com @fischaelameer Ergonomics
geildanke.com @fischaelameer It was the pioneer days; people had to make their own interrogation rooms. Out of cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,' it's not because I want you or because I can't have you. It's my estimation that every man ever got a statue made of him was one kind of sommbitch or another. Oh my god you will never believe what happened at school today. From beneath you, it devours. I am never gonna see a merman, ever. It was supposed to confuse him, but it just made him peppy. It was like the Heimlich, with stripes! How did your brain even learn human speech? I'm just so curious. Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's ludicrous to have these interlocking bodies and not...interlock. I just don't see why everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky world that still makes sense to me. You are talking crazy-person talk. http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer 70°
geildanke.com @fischaelameer 130° Comfortably bending 30° to each side
geildanke.com @fischaelameer 230° Stretching 80° to each side https://www.youtube.com/watch?v=00vzW2-PvvE
geildanke.com @fischaelameer 0.5m 20m https://www.youtube.com/watch?v=00vzW2-PvvE
geildanke.com @fischaelameer ~20px ~10ppd < 20px 60ppd
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameer avoid eyestrain: use darker colors avoid focussing on different depths do not trigger phobias use correct scales do not move things fast towards the camera do not attach things near the camera make the user comfortable
geildanke.com @fischaelameerIcon made by Freepik from www.flaticon.com
geildanke.com @fischaelameerIcon made by Freepik from www.flaticon.com
geildanke.com @fischaelameer
geildanke.com @fischaelameer
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer no acceleration do not move the horizon or the camera always keep a low latency and a high frame rate avoid flicker and blur add a stable focus point support short usage abstract design is better than realistic do not make your users sick!
geildanke.com @fischaelameer You are responsible for the 
 well-being of your users!
geildanke.com @fischaelameer http://www.uxofvr.com/ https://iswebvrready.org/ General information https://webvr-slack.herokuapp.com/ https://www.reddit.com/r/reactvr/ Community https://www.reddit.com/r/WebVR/ https://w3c.github.io/webvr/ https://github.com/googlevr/webvr-polyfill https://threejs.org/ API, frameworks, libraries https://facebookincubator.github.io/react-vr/index.html https://facebookincubator.github.io/react-vr/docs/getting-started.html https://github.com/facebookincubator/react-vr
geildanke.com @fischaelameer https://geildanke.com/en/vr Thank you! @fischaelameer

Goodbye, Flatland! An introduction to React VR and what it means for web developers