# 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](https://developers.google.com/vr/concepts/vrview) overview.

*Click and drag to move through the image.*

<br />

## 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](https://github.com/googlearchive/vrview/blob/master/examples/gallery/index.html)
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](https://googlearchive/vrview/blob/master/examples/hotspots/index.html)
of a photosphere where clicking on a hotspot changes the center of view.

## Self-hosting

Host the VR View
[sample code and media files](https://github.com/googlevr/vrview)
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.