Web VR Starter Kit is a Javascript library for easily creating virtual reality content and making it available in web browsers on a range of devices. The library includes a simplified API for creating an manipulating 3D objects.
To create a virtual reality scene, include the WebVR Starter Kit JavaScript file as a script tag in a webpage. The script will bootstrap an empty scene with controls for display and view-tracking options, depending on the hardware available.
WebVR requires a browser with WebGL support. The following device configurations are supported for display and head/view tracking:
The quickest way to get started is to load the empty JS Bin template and start writing commands in the JavaScript panel. As you type, the output panel will automatically reload every time you make a change. You can pop the output panel out into its own window to view in full screen or on an Oculus Rift (if available), or you can load the output page on a mobile device.
Alternatively, you can start with a blank web page hosted on your own server. Include the following script element anywhere in the page.
<script src="https://github.com/povdocs/webvr-starter-kit/raw/master//povdocs.github.io/webvr-starter-kit/build/vr.js"></script>
Create another script element containing the JavaScript commands that describe your scene. You can either include the script "inline" right in the same web page, or you can refer to an external JavaScript file. Just make sure this script element is placed after the one loading "vr.js".
<script>
VR.floor(); //make a floor
</script>
There are a few different ways that you can load media as part of your VR scene. The panorama
and image
objects take the URL of an image file. The sound
object takes an array of URLs of audio files, and the video
object takes an array of URLs of video files. There is a library of pre-defined materials (e.g. grass, stone, metal, wood), and you can also specify your own images to use as texture maps.
Texture maps for pre-defined materials are hosted as part of the WebVR Starter Kit, but your own media files need to be hosted elsewhere. You can use your own web server if you have one, but it needs to be configured to use Cross-Origin Resource Sharing headers, which can be tricky to set up.
There are some free services you can use to host your media with the correct server settings.
If you have an image you want to use, you can upload it to imgur.com. Once the image is uploaded, follow the link to share it and look for the "direct" image URL. That will link directly to the png or jpg file, and it's the URL to use in your code.
You can also use any image that's already hosted on imgur, but check the copyright terms on the site and on the particular image.
If you have a Dropbox account, you can copy your media files into your "Public" folder. Log into Dropbox through their website and browse to the Public folder. Click on the file you want to use for a prompt to view the public URL of that file. Unlike imgur, Dropbox can host audio and video files.
todo: archive.org
The simplified API is a wrapper for three.js, a JavaScript library for creating 3D scenes using WebGL. three.js is more powerful than the WebVR Starter Kit API, but more difficult to use. If you prefer, you can use three.js directly to build your scene, but you will not be able to use the wrapper objects on any objects you create with three.js.
If you prefer to use the simplified API for part of your code and use three.js for a limited set of advanced operations, each object created has a .object
property that points to its three.js object.
var box = VR.box();
console.log(box.object instanceof THREE.Mesh); // true
todo: describe common options and methods for all objects
name
material
color
Create a cube.
No options.
Create a cylinder. You can also create a cone by change the radius at one end to zero.
radiusTop
— Radius of the cylinder at the top. Default: 0.5radiusBottom
— Radius of the cylinder at the bottom. Default: 0.5height
— Height of the cylinder. Default: 1radiusSegments
— Number of segmented faces around the circumference of the cylinder. Default: 16heightSegments
— Number of rows of faces along the height of the cylinder. Default: 1openEnded
— A Boolean indicating whether the ends of the cylinder are open or capped. Default: false (capped)Create a sphere. Parts of spheres or slices can be created by specifying different values for phiStart
, phiLength
, thetaStart
or thetaLength
.
radius
— sphere radius. Default: 0.5widthSegments
— number of horizontal segments. (Minimum value is 3). Default: 16heightSegments
— number of vertical segments. (Minimum value is 2). Default: 12phiStart
— specify horizontal starting angle. Default: 0phiLength
— specify horizontal sweep angle size. Default: PI * 2thetaStart
— specify vertical starting angle. Default: 0thetaLength
— specify vertical sweep angle size. Default: PICreate a torus (like a donut).
radius
— Default: 0.5tube
— Diameter of the tube. Default: 0.125 (i.e. 1/8th)radialSegments
— Default: 12tubularSegments
— Default: 16arc
— Central angle, or how much around the center point the torus is filled in. Default: PI * 2radius
— Radius of the circle. Default: 100segments
— Number of segments. Default: 16A plane displaying an image.
src
- A url pointing to the image fileA plane displaying a video.
src
- A url or array of urls pointing to the video file(s). Provide multiple sources for different formats to support all browsers.Video objects have some unique methods and properties for inspecting and controlling the state of the video.
Play the video.
Pause the video.
Pass a mime type (e.g. "video/webm"
) to determine whether the video can play a given format.
The current time within the video (in seconds) of the play head. (Read only)
The total duration of the video in seconds. This value is not known until the video starts loading. (Read only)
The volume level of the video. It can be set to any value between 0 and 1.
The height in pixels of the video source. This value is not known until the video starts loading. (Read only)
The width in pixels of the video source. This value is not known until the video starts loading. (Read only)
A boolean value that reports whether the video is paused (true) or playing (false). (Read only)
Safari and Internet Explorer cannot display cross-origin videos, i.e. files served from a different web server than the web page. So you must host the web page on your own server if you want to use video on all browsers. JSBin will not work.
Mobile Safari is only capable of playing one video at a time, and only on iPad.
A very large sphere with an image displayed on the inside. This is useful for loading an image to be used as a sky or a landscape. It works best if most objects in the photo are far away.
Spherical photos can be taken with the Android Camera or a similar app on an iPhone. They can also be made manually.
Stereoscopic (3D) panoramas can be displayed by setting the stereo
option, if the left and right eye views are included side-by-side or vertically in the same image file.
src
- A url pointing to the image filestereo
- a string, either "horizontal" or "vertical" (optional).Creates two-dimensional text. Observes new-line characters.
text
- a string representing the text to renderfont
- a string, the font style, size and familytextAlign
- 'left', 'right', 'center', 'justify', 'start' or 'end'textBaseline
- 'top', 'hanging', 'middle', 'alphabetic', 'ideographic' or 'bottom'direction
- 'ltr' (left to right) or 'rtl' (right to left)fillStyle
- same as the 2d canvas propertywrap
- the maximum width of the text object in meters. Any text longer than this will wrap to the next line.resolution
- the number of "pixels" equivalent to 1 meter in 3D space. Making this number higher will increase the fidelity of the text but will also require making the font size proportionally larger. (default is 256)The width of the object containing the text. This will depend on the length of the text, the font size and the wrap
setting.
The height of the object containing the text. This will depend on the length of the text, the number of lines and the font size.
An empty object, not displayed. Can be used to group other objects.
No options.
The following methods are available on all object types for manipulating the shape, size, material, orientation, position and any other aspects of that object.
All methods (except for ones that create child objects), return the object itself, so methods can be chained:
// create a box, move it up 2 meters, and set the material to "wood"
VR.box().moveUp(2).setMaterial('wood');
Make the object invisible. All objects are visible by default.
Make the object visible, if it was previously made invisible.
Objects can be created as "child" of a parent object. This is useful for creating more complex objects out of the simple primitives or for moving groups of objects together. All the object creation methods listed above on the main VR
object are available on every other object created.
The position, rotation and size of child objects will be re
The "empty" object type is useful as an invisible parent object below which other objects can be grouped.
Certain types of "events" are available to notify your code when interesting things happen, such as the user looking at an object or shaking the phone. This method provides a way to specify the event type and a "callback function" to be run when the event occurs.
Events are listed below. Not all events are available on all devices.
event
- A string representing the name of the event type to listen forcallback
- A function to be run when the event is triggered. The callback function may be given certain parameters, depending on the type of eventlookat
- The viewer looked directly at an object. There is one parameter, target
: the THREE.js object in questionlookaway
- The viewer looked away from an object. There is one parameter, target
: the THREE.js object in questionshake
- The user shook the device. Mostly only works on mobile devices. Does not work on head-mounted displays.fullscreenchange
- The view has either entered or exited full screen mode.devicechange
- The device used to display and track orientation has been detected. There is one parameter, mode
: a string representing the type of device. "devicemotion" for a mobile phone/tablet, "hmd" for a head-mounted display like the Oculus Rift. If there is no orientation device detected, like on a desktop computer without a head-mounted display, this event will not fire.When the user shakes the device, make the box invisible. Shake it again to bring it back.
var box = VR.box();
VR.on('shake', function () {
if (box.visble) {
box.hide();
} else {
box.show();
}
});
Prevent any previously registered event callbacks from running in the future.
event
- A string representing the name of the event type.callback
- A callback function previously registered with VR.on()
with the same callback type. This callback will no longer be run for this method.This method can be passed a callback function, which is run every time a new frame is rendered. Objects in the scene can be animated by changing their position, scale or rotation according to how much time has passed since the last update.
callback
- A function to be run on every frame. Receives two arguments: delta
, the number of seconds since the last frame, and time
, the current time in secondsCreate a box and make it rotate, one full rotation per second.
var box = VR.box();
VR.animate(function (delta) {
box.rotateY(delta * Math.PI 2);
});
Stop any or all animation callbacks from running.
callback
- The same function passed to VR.animate
that you want to stop from running. This parameter is optional. If no function is passed, all animations will be stopped.Cause the device to vibrate, if the browser and hardware support it. This is most likely to be available on mobile devices running Android with Chrome or Firefox. If vibration is not supported, nothing will happen.
pattern
- A pattern of vibration and pause intervals. This can either be a number, representing the duration of a single vibration in milliseconds, or an array of numbers representing alternating vibrations and pauses in milliseconds.When the user looks at the box, vibrate once for one quarter of a second. When the user looks at the sphere, vibrate 'SOS' in Morse code.
var box = VR.box().moveX(-2);
var sphere = VR.sphere().moveX(2);
VR.on('lookat', function (target) {
if (target === box.object) {
// 1/4 of 1000 milliseconds = 250 milliseconds
VR.vibrate(250);
} else if (target === sphere.object) {
VR.vibrate([100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100]);
}
});
Reset the rotation of the viewer so that whichever direction they are looking at the time VR.zeroSensor()
is called gets set back to the original "zero" direction they were facing when the web page loaded.
The following properties are available on the global VR
object.
A VRObject
representing the viewer. This object can be manipulated like any other object, and child objects can be attached to it, like a vehicle or tools. The body object can be moved around the scene to give the viewer different perspectives.
The body starts out 1.5 meters high and 4 meters back from the center point (0, 0, 0) of the scene.
Warning: Be careful about animating movement of the body, as it may cause motion sickness. It's best to constrain movement to the direction the viewer is looking. Any movement backwards or to the side should be slow. Starting and stopping of movement should be abrupt and the speed should remain constant, as acceleration in any direction is known to cause motion sickness.
A VRObject
representing the camera. The camera is a child object of the body. It's best not to move, rotate or scale the camera. Instead, move the body.
Images or objects can be scaled down and attached to the front of the camera to act as a "heads up display."
The HTML canvas
element to which the scene is being rendered.
An object on which all material-related functions and properties are attached:
VR.materials.library
- an array of strings representing the names of built-in material presetsVR.materials.textures
- an array of THREE.Texture
objects used by built-in materialsThe THREE.Scene
object that is the parent of all other three.js objects.
Code, concept and design by Brian Chirls, POV Digital Technology Fellow