Looking for the last version ?

This is the documentation for Photo Sphere Viewer 3. Go to Photo Sphere Viewer 4.


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


Let's go!

Include all JS & CSS files in your page manually or with your favorite bundler and init the viewer.

<div id="viewer"></div>

  #viewer {
    width: 100vw;
    height: 50vh;

  var viewer = new PhotoSphereViewer({
    container: 'viewer',
    panorama: 'path/to/panorama.jpg'

Cropped panoramas

If your image is not covering a full 360°×180° sphere, it will be deformed. You can fix it by providing cropping data.

Gyroscope support

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


VR support

In order to be able to display the panorama in VR mode, Photo Sphere Viewer requires the following files from Three.js examples (also available in three.js-examples Bower package) :

As well as the NoSleep.js library.


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).


Name type default description
container HTMLElement
required HTML element which will contain the panorama, or identifier of the element.
panorama 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.
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.
sphere_correction object {pan:0, tilt:0, roll: 0} Sphere rotation angles, in radians.
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
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 Enables zoom with the mouse wheel.
mousemove boolean true Enables panorama rotation with the mouse cursor.
mousemove_hover boolean false Rotate the panorama just by moving the cursor above the view instead of click+move.
touchmove_two_fingers boolean false Requires two fingers to rotate the panorama. This allows standard touch-scroll navigation in the page containing the viewer. If enabled, an overlay asking the user to use two fingers is displayed when only one touch is detected.
keyboard Object | boolean Enable and configure keyboard navigation in fullscreen. It is a map defining key code->action. Set to false to disable.
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.
with_credentials boolean false Set to true to use credentials for HTTP requests.

Advanced options

Name type default description
move_speed double 1 Speed multiplicator for manual moves.
zoom_speed double 2 Speed multiplicator for zooms (with mouse wheel or fingers pinch).
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 0 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.
mousewheel_factor double 1 Zoom speed multiplicator when using the mouse wheel.


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() {
    x: 1500,
    y: 1000


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, stereo, 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: [
      id: 'my-button',
      title: 'Hello world',
      className: 'custom-button',
      content: 'Custom',
      onClick: function() {
        alert('Hello from custom button');

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().