Presentation

Photo Sphere Viewer is a JavaScript library which renders 360° panoramas shots with Photo Sphere, the new camera mode of Android 4.2 Jelly Bean and above. It also supports cube panoramas.

Photo Sphere Viewer is pure JS and based on Three.js, allowing very good performances on WebGL enabled systems (most recent browsers) and reasonably good performances on other systems supporting HTML Canvas.

And it works with touch screens too !

Thanks to @JeremyHeleine

I forked the original Photo Sphere Viewer by Jérémy Heleine to provide a better JS architecture and a bunch of new features.

Getting started

Download Photo Sphere Viewer

Dependencies

Markup

Include all JS & CSS files in your page and you are ready.

<link rel="stylesheet" href="Photo-Sphere-Viewer/dist/photo-sphere-viewer.min.css">

<script src="three.js/three.min.js"></script>
<script src="D.js/lib/D.min.js"></script>
<script src="uevent/uevent.min.js"></script>
<script src="doT/doT.min.js"></script>
<script src="Photo-Sphere-Viewer/dist/photo-sphere-viewer.min.js"></script>

<script>
  var viewer = PhotoSphereViewer({
    container: 'container-id',
    panorama: 'path/to/panorama.jpg'
  });
</script>

PSV can also be used with CommonJS :

require(['photo-sphere-viewer'], function(PhotoSphereViewer) {
  var viewer = PhotoSphereViewer({
    container: 'container-id',
    panorama: 'path/to/panorama.jpg'
  });
});

Canvas rendering

In order to get Photo Sphere Viewer working on browsers without WebGL you will need some additional files from Three.js examples (also available in three.js-examples Bower package) :

Gyroscope support

In order to be able to respond to device gyroscope (gyroscope option), Photo Sphere Viewer requires the following files from Three.js examples (also available in three.js-examples Bower package) :

Usage

Angles definition

Photo Sphere Viewer uses a lot of angles for it's configuration, most of them can be defined in radians by using a simple number (3.5) or in degrees using the "deg" prefix ('55deg').

Positions definition

Some methods take a position parameter. It is an object with either longitude and latitude properties (radians or degrees) or x and y properies (corresponding to the pixel position on the source panorama file).

Options

Name type default description
container HTMLElement
String
required HTML element which will contain the panorama, or identifier of the element.
panorama String
String[]
Object<String, String>
required Path to the panorama image(s). It must be a single string for equirectangular panoramas and an array or an object for cubemaps.
caption String null A text (can contain HTML) displayed in the navbar. If the navbar is disabled it will be shown anyway but with no button.
markers Array [] List of markers.
autoload boolean true Automatically load the panorama, if false you must use load method later.
min_fov integer 30 Minimal field of view (corresponds to max zoom), between 1 and 179.
max_fov integer 90 Maximal field of view (corresponds to min zoom), between 1 and 179.
default_fov integer max_fov Initial field of view, between min_fov and max_fov.
fisheye boolean|integer false Enable fisheye effect with true or specify effect strength (true = 1.0). This mode can have side-effects on markers rendering.
default_long double 0 Initial longitude, between 0 and 2π.
default_lat double 0 Initial latitude, between -π/2 and π/2.
longitude_range double[] Viewable longitude range. Examples:
[0, Math.PI], [-3*Math.PI/4, 3*Math.PI/4].
latitude_range double[] [π/2, -π/2] Viewable latitude range.
time_anim integer
boolean
2000 Idle time (milliseconds) before the panorama automatically starts rotating. false to deactivate.
anim_speed string '2rpm' Automatic rotation speed in radians/degrees/revolutions per second/minute.
anim_lat double default_lat Latitude at which the automatic rotation is performed.
navbar boolean|array Enable or disable the navigation bar, you can also choose which buttons are displayed and even add custom buttons. See below.
lang Object Text of navbar buttons tooltips.
loading_img String null Path to an image displayed in the center of the loading circle.
loading_txt String 'Loading...' Text displayed in the center of the loading circle, only if loading_img is not provided.
mousewheel boolean true Listen to mouse wheel events to zoom in and out.
mousemove boolean true Listen to mouse click+move events to rotate the view.
keyboard boolean true Enabled keyboard navigation in fullscreen.
gyroscope boolean false Enable gyroscope navigation and add a navbar button when the device supports it.
size Object null The final size if the panorama container (e.g. {width: 500, height: 300}. By default the size of container is used and is followed during window resizes.
transition Object Configuration of the transition effect between panoramas.

Advanced options

Name type default description
move_speed double 1 Speed multiplicator for manual moves.
usexmpdata boolean true Read real image size from XMP data, must be kept true if the panorama has been cropped after shot.
pano_data object Manually define cropping config (if usexmpdata = false or no XMP tag is found) example.
cache_texture integer 5 Number of texture objects to cache into memory, this is to prevent network overload when calling setPanorama multiple times.
tooltip object Configuration of the tooltip. This only needs to be changed if the CSS is modified.
move_inertia boolean true Enabled smooth animation after a manual move.
click_event_on_marker boolean false A click on a marker will trigger a click event as well as select-marker.

Methods

All useful methods are documented in the API documentation

To call a method you need to keep a reference to the viewer (created with new keyword). It's good practice to wait for the ready event before doing anything.

viewer.on('ready', function() {
  viewer.rotate({
    x: 1500,
    y: 1000
  });
});

Events

On the viewer you can also use the on method to listen to various events.

navbar is an array which can contain the following core buttons: autorotate, zoom, download, markers, gyroscope, fullscreen, as well as caption and objects to create custom buttons :

Name description
id The unique identifier of the button.
title The button tooltip.
content The content of the button.
className A CSS class added to the button element.
onClick Function called when the button is clicked.
disabled If the button must be disabled by default.
hidden If the button must be hidden by default.

This example uses some core buttons and a custom one.

new PhotoSphereViewer({
  container: 'container-id',
  panorama: 'path/to/panorama.jpg',
  navbar: [
    'autorotate',
    'zoom',
    'markers',
    {
      id: 'my-button',
      title: 'Hello world',
      className: 'custom-button',
      content: 'Custom',
      onClick: function() {
        alert('Hello from custom button');
      }
    },
    'caption',
    'fullscreen'
  ]
});

Altering the buttons

After the viewer creation you cannot add or remove buttons but you can change their visibility. Use the getNavbarButton(id) method the get a button by its id (works for core buttons too). You will get an object with the following methods: disable(), enable(), hide(), show().

viewer.getNavbarButton('my-button').hide();