November 6, 2019 update:
  • There's a new open source Cardboard SDK for iOS and Android NDK that offers a streamlined API, improved device compatibility, and built-in viewer profile QR code scanning. A corresponding Unity package (SDK) is planned for a future release. We recommend that all developers actively building for Google Cardboard migrate (iOS, Android NDK) to the new Cardboard SDK.
October 15, 2019 update:
  • The Daydream View VR headset is no longer available for purchase. However, you can continue to use the existing Google VR SDK to update and distribute your apps to the Google Play Store, and make them available to users in the Daydream app.

VR View for the Web

You can embed 360° photos and videos into a website using VR View. This can be done via a JavaScript API that creates and controls the contents of an iframe or by explicitly declaring the iframe itself.

For more information on supported formats and other considerations, see our 360° Media overview.

Click and drag to move through the image.

Getting started

To use VR View, include the Google-provided vrview.min.js script within your HTML:

<script src="https://storage.googleapis.com/vrview/2.0/build/vrview.min.js"></script>

Next, add a placeholder where you want the iframe that will contain the photosphere content.

<div id='vrview'></div>

When the VR View is loaded, this placeholder line will be replaced by an iframe with class='vrview'.

Instantiate the VR View after the page loads by listening for the load event:

window.addEventListener('load', onVrViewLoad);

function onVrViewLoad() {
  // Selector '#vrview' finds element with id 'vrview'.
  var vrView = new VRView.Player('#vrview', {
    video: '/url/to/video.mp4',
    is_stereo: true
  });
}

Note that by itself, this is equivalent to simply declaring an iframe with the same parameters:

<iframe src="https://storage.googleapis.com/vrview/2.0/embed?video=/url/to/video.mp4&is_stereo=true">
</iframe>

However, using the VR View JavaScript API offers additional features not available when explicitly declaring an iframe.

VR View

You create a new VR View by calling the VRView.Player constructor and passing it a selector that determines where to put the VR View and a parameters bundle. The selector should point to the id of the div placeholder line you included in your HTML.

For example,

// Selector '#vrview' finds element with id 'vrview'.
var vrView = new VRView.Player('#vrview', {
  video: '/url/to/video.mp4',
  is_stereo: true
});

A complete list of configuration parameters can be found in the table below.

Name Type Parameter description
video String URL to a 360° video file or an adaptive streaming manifest file (.mpd or .m3u8). Exactly one of video or image is required.
image String URL to a 360° image file. Exactly one of video or image is required.
width String String value for the iframe's width attribute.
Required if using the JavaScript API. Has no effect if used within an iframe.
height String String value for the iframe's height attribute.
Required if using the JavaScript API. Has no effect if used within an iframe.
preview String (Optional) URL to a preview image for a 360° image file.
is_stereo Boolean (Optional) Indicates whether the content at the image or video URL is stereo.
is_debug Boolean (Optional) When true, turns on debug features like rendering hotspots ad showing the FPS meter.
is_vr_off Boolean (Optional) When true, disables the VR mode button.
is_autopan_off Boolean (Optional) When true, disables the autopan introduction on desktop.
default_yaw Number (Optional) Numeric angle in degrees of the initial heading for the 360° content. By default, the camera points at the center of the underlying image.
is_yaw_only Boolean (Optional) When true, prevents roll and pitch. This is intended for stereo panoramas.

VR View events

VR View emits four different types of events, which must be registered using the VRView.on(String event, function handleEvent) function. The on() function takes in two parameters, the name of the event type as a String, and a function that handles the event. For instance,

VRView.on('click', function(event) {
  if (event.id == myHotspotId) {
    // Handle hotspot click.
  }
});

The types of events on() can register are:

  • ready: VR View loaded its initial contents and is now ready to accept commands.

  • error: VR View reports an error, such as when content couldn't be loaded.

  • click: The VR View is clicked (tapped on mobile, gazed on in VR mode). Can be used to register clicks to move to the next slide in a slide show, or to register when a user clicks a hotspot.

  • modechange: VR View changed modes, such as when the user enters VR or fullscreen mode. You can use this to track user behavior by registering callbacks whenever the user changes modes.

Video controls

You can control a VR View video using the play(), pause(), and setVolume() functions.

  • VRView.play(): If the VR View is a video, calling play() resumes the video. If the VR View is not a video, play() throws an error.
  • VRView.pause(): If the VR View is a video, calling pause() pauses the video. If the VR View is not a video, pause() throws an error.
  • VRView.setVolume(double fractionVol): If the VR View is a video, calling setVolume() sets the volume to the given fraction of the max volume.

    Platform Mute Adjust volume Unmute / Full volume
    Android setVolume(0) Set fractionVol to any value in range [0, 1].
    For example, setVolume(0.5).
    setVolume(1)
    iOS setVolume(0) Not available. setVolume(1)

Loading new content

You can load new content into the iframe without reloading the iframe itself using the setContentInfo() function.

setContentInfo()

VRView.setContentInfo() takes in a URL to a 360° photo or video as a string and a bundle of parameters.

vrView.setContentInfo({
  image: '/url/to/amazing-4096.jpg',
  preview:'/url/to/amazing-512.jpg',
  is_stereo: true
});

setContentInfo() can use the same parameters as the VRView constructor with the exception of width and height.

See the New7Wonders of World example of swapping content in and out.

Hotspots

Hotspots are regions on a photosphere that users can interact with. Hotspots can be rendered on all platforms, but the way users interact with them differs.

  • On desktop, hovering over the hotspot with the mouse cursor changes it visually, and clicking it activates it.

  • On mobile, tapping the hotspot activates it.

  • In VR mode, gazing at a photosphere containing hotspots causes a reticle to be rendered, which will change states when it focuses on a hotspot. At that point, tapping anywhere on the screen will activate it.

Defining hotspots

Hotspots are circular regions on the sphere with a given ID string, center coordinates, radius, and ID. They can be added using the vrView.addHotspot() function.

For example:

vrView.addHotspot('dining-room', {
  pitch: 30, // In degrees. Up is positive.
  yaw: 20, // In degrees. To the right is positive.
  radius: 0.05, // Radius of the circular target in meters.
  distance: 2 // Distance of target from camera in meters.
});

The coordinates, determined by pitch and yaw, are with respect to spherical coordinates.

  • The default center of view is at (0, 0).
  • The pitch range is [-90, 90] with positive values corresponding to up.
  • The yaw range is [-180, 180] with positive values corresponding to the right.

Hotspot events

To add an event when a hotspot is clicked, use the on() function:

vrView.on('click', function(event) {
  if (event.id == myHotspotId) {
    // Handle hotspot click.
  }
});

See the American Museum of Natural History of a photosphere where clicking on a hotspot changes the center of view.

Self-hosting

Host the VR View sample code and media files on your own server. Hosting the code yourself avoids several known issues with browsers (see below).

Known issues on the web

  • 360° images will have incorrect orientation in iOS Safari if you explicitly declare your iframe (instead of using the JavaScript API) and the code and images are hosted on different servers.

  • 360° videos do not work in OSX Safari if the media and the VR View code are hosted on different servers.

  • Images that are not power-of-two and square may not display correctly in Chrome and Safari iOS 8.