Pannellum is a lightweight, free, and open source panorama viewer for the web. Built using HTML5, CSS3, JavaScript, and WebGL, it is plug-in free. It can be deployed easily as a single file, just 15kB gzipped, and then embedded into pages as an <iframe>. A configuration utility is included to generate the required code for embedding.

For more information, see Development can be followed on GitHub.

362 Responses to Pannellum

  1. Phineas says:

    Firstly, congratulations on some really good work here.

    I have been trying to integrate this on my personal website to display all my PhotoSynth images I’ve taken on my travels, and I have stumbled across a bug.

    When running this app from an iFrame, the fullscreen mode works fine, but when you go back to regular screen, it throws a JS error and does not run the onFullScreenChange() function, so you can’t return back into fullscreen mode after this without reloading the page.

    I believe that the solution to this would be to correctly reference the “fullwindowtoggle_button_active” or “fullwindowtoggle_button” elements from within the iframe parent page. I’m taking a look to see if I can figure out how to do it, but I thought that I would mention it to you, in case you knew of a quick solution.

    If I come up with a fix in the next couple of days, I shall post it here.

    Keep up the good work – Phineas.

  2. ulothix says:

    I just found your post on the Hugin mailing list about this panorama viewer. Really easy to use. Thanks for sharing this great piece of software!

  3. Ken Stroud says:

    Great piece of work! What would it take to make a stereo viewer? Two images that the user can zoom/pan and the second iframe stays in sync.

    • Matthew Petroff says:

      One could probably modify the copy of Pannellum used on the first iframe, and for each of the zoom/pan functions add “window.parent.getElementById(‘second_iframe_id’).contentWindow.function_name(parameters);” to mirror actions on the first panorama on the second (I haven’t tried it). To make it work both ways, one could add the opposite to the second iframe, but one would also have to add a parameter and check to each function to see if it was called by the other iframe to prevent infinite recursion. The other option would be to modify Pannellum to have two canvases, with different images in each.

  4. Xbo says:

    Pannellum seems to work great, but is it possible to make it work with images from ImageShack or Flickr for example? I tried with ImageShack without success!

    • Matthew Petroff says:

      Due to browser security restrictions, using an image from a remote URL requires CORS support. Since neither Flickr nor ImageShack support CORS, using images hosted by them in Pannellum is currently impossible.

  5. Serghei GM says:

    Hi Matthew,
    Really very nice panorama viewer.
    I was trying to get the angles (yaw, pitch) for the specific pixel. Any help would be appreciated.

    • Matthew Petroff says:

      I’m not entirely sure what you’re asking. If you want to know how Pannellum maps image pixels to the screen, see this PDF. If you want to know how an equirectangular images is projected on the image sphere look at this Wikipedia article.

    • Kirby Vandivort says:

      Hi. I was wondering this to. I’ll explain what I’m wanting.

      I am looking for a way to help me create custom JSON files. I want to be able to load an image into Pannellum and have it, via text overlay/debugging/i don’t really care what.., tell me the pitch, roll, and yaw, etc for the center of the screen. As I roll around, zoom in/out etc these numbers would change. Then, I could use those numbers when creating the JSON file to accurately place jump points, and so on.

      Is there a way to do this already that I’m just not aware of? It would be crazy helpful. Right now it is a matter of putting in random numbers and reloading until it gets to where we want it.

      More explanation needed? Just ask.


      • Matthew Petroff says:

        The development version has a hotSpotDebug option that prints the pitch and yaw of the mouse pointer to the console when the mouse button is clicked. I think this is what you’re looking for.

        • Kirby Vandivort says:

          Matthew, I’ve grabbed the dev version and I love it! Only suggestion.. would it be possible to also print out the current hfov? That way we could easily determine the parameters necessary to ‘create’ a given view. Thanks much!

        • Jaan says:

          Matthew, the hotSpotDebug option is a great time-saver. It may not be obvious for non-devs how to use it (or even activate it). You may want to throw in a sentence into the README.


          • Matthew Petroff says:

            I generally consider hot spots to be a somewhat advanced feature, so I don’t think the README is the best place. However, thanks to your suggestion, I expanded the documentation about the option in the hot spots example (and referenced the documentation in the tour example).

  6. Andreas Enz says:

    Hello Matthew!

    I’m really impressed with your HTML5 Pannellum Viewer. Is there any way to use it when the files (pannellum.htm and theimage.jpg) are stored locally on my machine? I can’t get it to work.


    • Matthew Petroff says:

      This is a result of browser security restrictions. If one has Python installed, one can run “python -m SimpleHTTPServer” from the Pannellum root directory and load the URL printed in the terminal. Otherwise, you need to find some other local web server or disable the security restrictions in your browser.

  7. Ivan says:

    I have a panorama image 10453*1177 24 PP, I use it replace the example directory img file and change the example.htm. Now it does not work. The screen is black. I compare the examplepano.jpg with my panorama file, the difference is the size, which is 5000*2500 24 pp. How to change the code to load my panorama image?
    When i resize my image file to 5000*563 , the panorama image file is loaded and it seemed stretched and have distortion, how to change parameter to fit the panorama image file?

    • Matthew Petroff says:

      Set the “vaov” parameter to the panorama’s vertical angle of view, which in this case appears to be 41 degrees. You can do this by adding “&vaov=41” to the end of the iframe URL. You were right about the size of your image. One ends up with a black screen when one’s image is too big for one’s graphics card/driver.

      • Gerhard says:

        I have two questions:

        1. How did you come to the number vaov=41?
        I use a downscaled Image 4096×2048 (from Ricoh Theta-S), and these is flickering when moving, and sometimes it goes to a black screen.
        When using vaov=180 it doesn’t flicker :)
        but I think, this is not the best value.

        2. How can I use bigger images also on mobile devices? when using 5376×2688 the iphone-device says this image is too big – maximum 4096 Pixels :(


        • Matthew Petroff says:

          The 41 degrees comes from the aspect ratio of Ivan’s image. For Ricoh Theta images, this parameter shouldn’t be specified; the default value of 180 degrees will then be used, which is correct, since the images cover the full sphere.

          While images with a width of 4096 pixels are supported by practically all devices, images with a width of 4097–8192 pixels are only supported by ~83% of devices (as of writing). To be able to use bigger images on these devices, a different kind of image needs to be used, either a cube map or multires image instead of an equirectangular image. Cube maps can be generated by many different software packages, while multires images are generated using Pannellum’s script.

          • John McDoy says:

            Hi! Compliments on the work done!

            I am a bit stuck; I use a Ricoh Theta, and since the images are too large to display on let’s say an iPhone (5376px wide), I get the warning that the panorama is too big.

            So I resize the image to a width of 4096px, but this doesn’t seem to help, I get the same warning even with the resized image.

            I use Photoshop in order to resize. I thought this might have something to do with the XMP data, but these are updated during the resize as well.

            There are though the following nodes in the metadata:


            I have not been able to edit this data. Could this be the issue? And how should I proceed?

            Any help is highly appreciated!

          • Matthew Petroff says:

            The metadata isn’t used for this check. Are you sure it’s loading the resized image? There could be a caching issue if you used the same image filename. I’m not sure how an image that’s small enough could trigger that message.

          • John McDoy says:

            It was indeed a caching issue — I still don’t know why, but it is resolved :)

            I have another question:
            viewer.on(‘mousedown’, someFunction);
            works fine for me.

            viewer.on(‘mouseup’, someFunction);
            does not.

            I am trying to get the pitch, yaw, Hfov of the new view, after moving the point of view, so mouseup is the right event, for some reason it is not triggering — any ideas?

          • Matthew Petroff says:

            It wasn’t implemented, so I just added it. See the events documentation.

  8. ivanxu says:

    Can I change parameter to fit the big input image file size? Which parameter should be used to change?
    If I want to achieve the effect like Google street view, let the image see from different distance, i.e from near to far, which parameter should to be adjusted?

  9. hardegg says:

    Hi Matthew,

    So impressive Pannellum is.

    It works well for me so far except for one question. During viewing panorama with mouse grabbing, how can I know the angle I’ve moved with respect to the original pose? To know how much angle I’ve gone along axis y (as defined in your document) is enough for me. Because I hope to show something at some specific angle pose, e.g., there is a person standing at some place I hope to show his name over his head every time this person appears when viewing the panorama.

    • Matthew Petroff says:

      The config.yaw and config.pitch variables (in git master) store the current center of the panorama with regards to the image center. I would recommend looking at the current hotspot code. It currently supports an information icon that will display arbitrary text when hovered over. It shouldn’t be difficult to extend this to display text directly instead of an icon.

      • Mat says:


        Thank you for your work, that’s really a great project !
        I checked out your projet, but I’m unable to use hot spots functionnality.

        Would you be nice enough to give me an example on how to use it ?

        I can’t get what those pitch and yaw values are for. I must say that I’m completelly new to imagery domain.

        • Matthew Petroff says:

          The pitch is the hot spot’s location above the horizon, and the yaw is the hot spot’s angle of displacement from the horizontal center of the panorama. Think of it like latitude and longitude on a globe respectively, except from inside the globe. See this example. Also, make sure you are using the development version (note that the copy in the build folder in Git is last stable release and is not up-to-date).

  10. Alan says:

    Hello Matthew,

    You’ve really done a great job! Here I have a little question on the buttons ‘zoom-in’ and ‘zoom-out’. How could I toggle them between hiding and show, or keep my own buttons on the panorama viewer even if the image has been changed? Thanks very much!

    • Matthew Petroff says:

      For the first part, document.getElementById('zoomcontrols').style.display = 'none'; will hide them, and document.getElementById('zoomcontrols').style.display = 'inline'; will show them again (from within pannellum.htm). For the second question, I’m not really sure what you’re asking.

  11. Adam says:

    Hi Matthew, Google recently released a new version of Chrome, and my panorama is not working anymore with it. I am using the newest one, 1.3, that works with having panorama image on different server than the main files. Any idea why this has happened?

    • Matthew Petroff says:

      I didn’t see anything in the changelog that would have caused it. With a link to the panorama that stopped working, I could try to debug it.

      • Adam says:

        I don’t know if this is any help but, I didn’t do anything with it it just stopped working after last chrome update, it loads the pano and after it finishes just displays black. It still works fine in firefox. Also I have gallery script which in the same time started to play. When clicked on next image it used to fade in next one, there is a black dotted background image for this purpose, I didn’t write the script but again it works in firefox not in chrome, something changed…

  12. Adam says:

    I have installed firebug and when I load panorama, on the script tab of firebug there is “access to restricted URI denied”. I have a portable chrome Version 31.0.1650.57 and everything in there works fine. 100% new version has faults

    • Matthew Petroff says:

      That’s an issue caused by the same-origin policy. I guess something changed in Chrome’s same-origin policy restrictions or CORS support.

      • Adam says:

        Just a recap.
        v31.0.1650.57 – Pannellum and my HTML5 gallery script are working fine and smooth.
        v32.0.1700.76 – Both are not working, script is messed up and pannellum shows black screen. Tried panos on krpano and swf worked fine, webgl ones were very very slow so I’ve updated my gfx drivers to newest ones and it solved performance problem but some glitches remained. Pannellum still didn’t work.
        v33.0.1750.29 beta-m.exe – Pannellum is working but slow, krpano newest version multires on their website works smooth. My script is still not working right. (this version without the driver didn’t work right)

        So basically why do they have to mess up so much…

  13. Daniele says:

    Hi Matthew! The first thing that I want to say is a big thanks for your work, is awesome and compatible with almost every browser (you can add IE 11 in the compatibility list); the second thing is a question, is there a way to start pannellum at a defined coordinates of view? Maybe with the pitch and yaw variables?

  14. Christoph says:

    Hello Matthew,

    i want to view my panorama with your great tool and downloaded it. Now the problem is that the included example.htm says “loading…” but nothing happens. On the other side the panorama on this website works fine with my chrome browser. Do you have any suggestions what could cause the example panorama not to load?

    Thanks a lot and best regards

    • Matthew Petroff says:

      Due to browser security restrictions, JavaScript can’t load files from file URIs. To use Pannellum locally, one needs a local web server. With Python 2, this can be done with python -m SimpleHTTPServer, and with Python 3, this can be done with python -m http.server, but any other local web server can be used as well.

      • Gary Warr says:

        Hi Mathew

        Thank you for this program. I’m sorry to trouble you, but I don’t know what you mean by ‘local server’. I’ve uploaded an sample image and the Pannellum.htm no problem, but nothing shows. I guess because I need to do something about this ‘local server’ thing.
        The servers hosting our website run Python but that’s the limit of my knowledge in that respect. I asked my IT support man and he didn’t know either. Can you explain what I need to do please?

        Many thanks


        • Matthew Petroff says:

          The need for a local server arises from browser security restrictions. Web browsers don’t allow access to `file://` URLs via JavaScript as it would allow a website to read files off of your hard drive. Therefore, Pannellum can only load images over HTTP or HTTPS (`http://` or `https://` URLs). Since serving file over HTTP requires a web server, you need to run a web server on your local machine to be able to load images that are stored on it. I hope this clears up the local server aspect for you.

          You wrote that you uploaded pannellum.htm and an image, which suggests to me that you are using a server. To display the image, you need to access pannellum.htm?panorama=imagename.jpg (if pannellum.htm and the image are in the same directory on the server). I recommend looking at the examples.

          • Gary Warr says:

            Thank you Matthew, but I’m still struggling with this.

            I don’t want to host any images on my machine, I’ve uploaded the test one to our website, the idea is to allow anybody who wants to see them. I have uploaded pannellum.htm and panorama=(imagename).jpg to our server. When I open the page with the iframe I get the pannellum.htm, and clicking just gets ‘loading’. The image is in the same directory, and it’s an http:// address
            Maybe it’s a problem with the image? The images were merged in Photoshop. Does it need to be saved in a special form or shape?
            I’ve been trying to make this work for 3 days straight now, it’s driving me mad!

            Many thanks


          • Matthew Petroff says:

            A problem with the image would result in the panorama being distorted but should not interfere with loading. Does anything print in your browser’s console (Ctrl+Shift+K in Firefox or Ctrl+Shift+C in Chrome)? If you switch to the network tab in your browser’s developer tools (and reload the page), does the correct image URL appear?

  15. Clay Jones says:

    Hi Matthew, I had a couple of quick questions.

    1) Using chrome 34.0.1847.116 m, any time I try to set autorotate=(cw|ccw) the view goes black on load and never recovers. Without it, the image loads fine and scrolls fine.

    2) Is it possible to control the top/bottom fill color if I set a vaov value?

    3) Any possiblility of adding pinch and spread touch control recognition?

    4) Failing touch controls, could the + and – buttons be separated more. It’s tough to touch when they’re so close.

    5) Your documentation talks about just putting pannellum.htm on the website, but I found I had to include the css and js directories and contents as well. Is that correct?

    6) Awesome work on Pannellum. It’s very top notch code.

    • Matthew Petroff says:

      1. The autorotate value needs to be a number. The bigger in magnitude the number, the faster the rotation. Positive is CCW; negative is CW.
      2. One would have to change the WebGL clear color in libpannellum.js.
      3. It’s on the to-do list, but adding CSS 3D support is a higher priority as most mobile devices don’t support WebGL.
      4. See previous.
      5. The documentation refers to a copy of pannellum.htm created using the build script (utils/build/ If using pannellum.htm from the src directory, the rest of that directory’s contents are also needed. Using the former on a website is preferable as it is much smaller.
      6. Thanks!

  16. ulothix says:

    I think there is a bug in the code rendering the hotspot locations in the master in pannellum.js:459:
    if((hs.yaw -90 && z 90 || hs.yaw <= -90 && z <= 0)) {
    but instead it should be
    if((hs.yaw -90 && z 90 || hs.yaw <= -90) && z <= 0)) {
    Mind the added parentheses in the second line of the condition.
    Otherwise hotspot locations with a yaw bigger than 90 never get rendered.

    Apart from that I do really like the new features of the json markup for the tours and the hotspots! Appreciate your effort and work!

    • ulothix says:

      Sorry, the line number was off, and besides the code got a little messed up by the formatting.
      so line 513 in pannellum.js should read (hs.yaw > 90 || hs.yaw <= -90 && z <= 0)) { instead of (hs.yaw > 90 || hs.yaw <= -90 && z <= 0)) {

      • ulothix says:

        And this time I forgot to add the parentheses that actually fix the bug ;-)
        ((hs.yaw > 90 || hs.yaw <= -90) && z <= 0)) {

        • Matthew Petroff says:

          While I was aware of the bug, I hadn’t gotten around to tracking it down. Thanks!

  17. john says:

    Hi Mathew and thanks for your great work on the Pannellum panorama viewer tool. I have a couple of question about Pannellum.
    First, I would like to ask you if is it possible to load Pannellum without using an iframe. Moreover, is there an API available (I could not find anything relevant in the documentation, but it is worth asking you directly) that I could use in order to get events such as panorama change in tour mode, panorama angle change event and change panorama angle view on the fly etc.

    Thanks in advance, best regards and keep up the good work.

    • Matthew Petroff says:

      At the moment, it only loads using an iframe and doesn’t support any events. I originally wrote it this way to avoid any style or scripting conflicts with the parent page and so something would be displayed when JavaScript is disabled. However, I’m considering moving to JavaScript loading for better integration support as you describe.

  18. Gumir J says:

    Hey Matthew, at first glance, this new panoramic viewer really has great potential!!! When I first saw three.js, there is no doubt knew that someday this script will be adapted for further development.
    Your development is very good at its start-up. BUT it can make a very wonderful one little nuance – is the presence of Inertia of Movement.
    This is an important yet for true browsing of panoramas…
    Happy Programming :)

  19. Xbo says:

    How to make Pannellum work with Google Drive?
    Images address seems to always change! It works only for few hours!?

    • Matthew Petroff says:

      I have no idea what links you’re using. The hosting links from the details panel don’t change.

      • Xbo says:

        When you want to share a file in Google Drive, the “sharing links” display the files in Google Drive.
        So, in Google Drive, I open my pano image with the link at the top right of the page in an external window, with a right clic I can copy the image URL ( etc…). I can display the image in a web browser with this URL, but only for few hours. I have a 403 error with this message : “Your client does not have permission to get URL”
        If I go back in Google Drive, the image URL have changed !!
        What link I have to use to make it work in Pannellum ?

          • Xbo says:

            Thank you so much; it works better like that!

            But now I have another big problem.
            It works locally, but on my web site it doesn’t work at all.
            Is it possible the web server prevents Pannellum working? (PHP and MySQL forbidden)


          • Matthew Petroff says:

            The web server is just serving a static file, pannellum.htm, so the lack of PHP doesn’t affect Pannellum. Do you have either an error message or a link to the broken panorama?

          • Xbo says:

            No error message, perhaps image size, but it works locally.
            Here is a link.

          • Matthew Petroff says:

            Your host is inserting tracking code into pannellum.htm. Besides being a questionable practice to begin with, they’re doing it in a syntactically incorrect manner, which is breaking Pannellum. You need to either find some way to stop your host from doing this, or find somewhere else to host pannellum.htm; one way is to host it using Google Drive, the same way you are hosting your panorama.

          • Matthew Petroff says:

            Also, I would recommend rescaling your image down to 8192px wide, if not 4096px wide, for better support. At its present resolution, less than 30% of people can view it; this goes up to 78% for 8192px wide and 99% for 4096px wide.

          • Xbo says:

            My server is writing some tracking code in my pages since few months now… but It’s free !
            I hosted Pannellum.htm in Google Drive and it works !!
            But there is some problems with IE11.
            – With equirectangular pano, spaces ( ), accents (é) etc… in title parameter don’t work, Pannellum displays some squares.
            – With cubic pano, I have the error message “Your browser does not have the necessary WebGL support to display this panorama” (Works with equi.)

            Works fine with Chrome and Firefox.

  20. jm says:


    on my ipad i can’t see panorama i created (webgl error).

    this page with your panorama is working fine on my ipad, why ? what’s difference ?

    • Matthew Petroff says:

      This page is using a multres panorama, which breaks the image into a large number of small tiles. I suspect you are using a single equirectangular image, which is wider than 4096px, the maximum texture size for iOS devices. The easiest fix would be to scale down the image to 4096px.

  21. ghenz says:

    Hello Matthew! It’s a nice work and really easy to use. I had a couple of questions.
    1. How to make cubic and equirectangular work on Apple products (Safari, iOS), since it doesn’t work WebGL in default settings.
    2. I’m planning build a web interface to add hotspots dynamically with jQuery draggable; how to convert x,y pixels equirectangular coordinate into yaw and pitch?

    • Matthew Petroff says:

      1. Cubic and equirectangular panoramas should work on iOS 8+ but not on previous versions due to their lack of WebGL support.
      2. yaw = (x - width / 2) / width * 180, pitch = (height / 2 - y) / height * 90

      • ghenz says:

        thanks for the fast response it save my day.
        yes its work on IOS 8+. and the pixel to screen formula i modified it a bit and its work well.
        yaw = (((x - width / 2) / width * 180)*2)*-1, pitch = ((height / 2 - y) / height * 90)*2
        I’ve tried generate multires image tools with 3000×1500 image dimension, it generated into 512 tile resolution. its work on almost all device. But I still have some questions, why i cant pinch to zoom in mobile and why hotspot marker not working on IOS when i touch it. do you have any idea?

        • Matthew Petroff says:

          I assume you’re using Pannellum 2.0.1. Pinch to zoom will be in the next release, which will be out soon. As for why the hotspots aren’t working, I don’t know as I don’t have an iOS device to test with.

  22. Xbo says:

    Hi Matthew,
    Could you please describe how to create a multires image.
    With I have the error message:
    “ImportError: no module named PIL”
    (Python 3.4.2, I have a ‘PIL’ folder in ‘site-packages’ folder, I have intalled PILLOW too.)
    Sorry I know nothing about Python, I don’t know how to use !
    Perhaps, there is already a documentation somewhere ?

    • Matthew Petroff says:

      There’s not really any documentation. The script needs Python 3 with Pillow installed. Based on your error, it seems that you don’t have Pillow installed properly; at least Python can’t find it. Try opening an interactive Python session and see what happens when you enter from PIL import Image. If that doesn’t work, there’s an issue with your Pillow install; if it does work, there’s an issue with my script.

      • Xbo says:

        I’ve reinstalled pillow and it seems to work but I have the error:
        “the following arguments are required: -n/–nona”
        I know Nona is part of Hugin. Do I have to install Hugin and how to tell where is nona ?
        I use OpenPano (PanoSalado) for flash panoramas and SaladoConverter is very easy to use !
        Is it possible to create the multires image for Pannellum with SaladoConverter ? It would be wonderful if we could use the same tiles for the two players.

        • Matthew Petroff says:

          It does require nona to be on the path environment variable; I really should add a note about that. I’ve never used PanoSalado or SaladoConverter, but I just looked at them. It seems that their Deep Zoom Cubic format is the same as Pannellum’s multires format; the configuration file just needs to be converted. I need to take a closer look to see exactly how to do that, though.

          • Xbo says:

            It works with SaladoConverter !!
            But we have to create manualy the “fallback” folder and rename zoom level folders (1,2,3 … instead of 8,9,10…)and it will be difficult to use the same tiles with the two players because OpenPano uses a 1px overlap.
            New questions:
            – Is there an option to change the mouse mode ?
            – I open my panos in Greybox and the fullscreen button doesn’t work.

          • Matthew Petroff says:

            From what I looked at, the overlap for SaladoPlayer is specified in its configuration file; however, I don’t know whether or not it actually works with a 0px overlap. I should note that the fallback images have the edge pixels duplicated to avoid visible seams at the cube edges in the CSS 3D renderer.

            For your new questions:
            1. There isn’t an option for changing the mouse mode.
            2. The iframe needs the allowfullscreen attribute; if it’s not working, I assume this is missing.

          • Xbo says:

            I tried with an Android divice with Chrome, pano opens in CSS 3D renderer and there is white stripes at the edges while moving !

            … and the compass is reversed.

          • Matthew Petroff says:

            Unfortunately, I don’t know of any way to prevent the stripes (otherwise I would have fixed it already). As for the compass being reversed, that seems to be a bug I’ve never noticed, and I will look into it.

  23. Xbo says:

    1. :(
    2. The allowfullscreen attribute is here. It works perfectly in a simple web page but when I open this page with Greybox no fullscreen. I never had problems with other players (video, pano…)

    • Matthew Petroff says:

      I might be misunderstanding you, but based on my brief look at the GreyBox documentation, you add a rel tag to a link, and it dynamically creates an iframe when the link is clicked. Are you linking directly to pannellum.htm or another page that has Pannellum embedded? If the latter is the case, both the iframe generated by GreyBox and the Pannellum iframe in the linked page need the allowfullscreen attribute. The easy way to tell if the attribute is missing somewhere is to use the Web Console in Firefox; a warning will be displayed when you click the fullscreen button if the attribute is missing (nothing happens in Chrome’s JavaScript Console).

      • Xbo says:

        You are totally right, the allowfullscreen attribute is missing in GreyBox, now I need to find how to add it in the code !
        Thank you very much.

  24. Xbo says:

    For the compass, I removed - before config.yaw and it seems to work but I don’t know if it creates other problem !

    • Matthew Petroff says:

      I’m unable to reproduce inconsistent compass behavior in Chrome for Android. It works the same for me as it does in desktop browsers.

  25. Xbo says:

    northOffset change nothing because compass turns the wrong way ! Is there something I don’t understand in the compass parameters ?

    • Xbo says:

      Your compass on this page turns the wrong way !! (George Peabody Library)

      • Matthew Petroff says:

        Actually, it points the way I intended it to point. The black arrow always points north, just like on a real compass (although the arrow is usually red).

        • Xbo says:

          It’s not the problem ! When you look North, (Black arrow up) you move the pano to see west, (The left side) the compass turns right to show east.
          For me North is UP, South is down, West is left and east is Right ! I think it is the same thing for everybody.

          • Matthew Petroff says:

            I still don’t follow. Looking north (black arrow up) and moving to look to the west, the compass turns clockwise, and the black arrow now points to the right. West is now pointing up.

  26. Xbo says:

    Ok,I understand your point of view, I found easier to read when the arrow shows what you are looking. (You look West, arrow shows West)

  27. Tomas Holusa says:

    Thanks for a great piece of work! Yesterday I decided to replace spherical panoramas on my old webpages (using flash) with something modern. I came across your Pannellum and it worked as a charm! I think there is a tiny error in the JSON doc in vOffset. This should be useful when vaov is non-180 (not nonzero) correct?

  28. Hi Matthew

    For a while I’ve been looking to replace the QuickTime plug in VR scenes on my website with HTML5 code. Pannellum looks to be the perfect tool. I congratulate you on a fantastic job.

    I have done some basic testing with an edited JSON file, and have a single scene running nicely.

    Is it possible to use javascript to read and to control the pan/yaw, tilt/pitch , and zoom independently? I would like to be able to zoom in to a specific point, and then a second point, before loading the next location in the tour (something I managed in QuickTime and give the impression of movement along path)?

    With QuickTime I would use javascript ActalPan=document.QTVR.GetPanAngle() I’m hoping I can use something similar.

    Is it also possible to use javascript to read the Pannellum scene name?

    Many thanks in advance, and best wishes


    • Matthew Petroff says:

      Currently, there isn’t really a good way for external JavaScript to interact with Pannellum; I’m working on a proper JavaScript API, but that isn’t done yet. For the time being, something along the lines of var pano = document.getElementById('pano').contentWindow; var pitch = pano.config.pitch; var yaw = pano.config.yaw; var scene = pano.config.activeScene; will allow you to read values; after changing a value (except activeScene), run pano.animate(); to update the rendering. Essentially, what you describe probably can be done right now without modifying the Pannellum source, but its a bit difficult and should be easier once I finish the API.

      • Hi Matthew.

        I had a play with the script you suggested and it works a treat. Should be able to do everything I wanted to.

        Many thanks


        • Hi Matthew

          Following your advice, I thought you might be interested to see on-going progress with using javascript to pan, tilt, and zoom Pannellum before moving to the next location / panorama. See

          I’m really pleased with the results.

          I am having some difficulty on two separate topics.

          1) Preventing the panorama from being warped when not full 180 hfov, or from not seeing any empty black space when I’ve added height to the panorama to make it equivalent to 180 hfov. I’ve experimented with setting maxPitch, and hoav with and without padding the panorama to full equirectangular image. But I’m unable to get a happy medium.

          2) The site works well on Windows Browsers, on Android devices, but not on my iPhone IOS 8.4. on which the pannellum image is a distorted view of the upper section of the panorama.

          Are you able to offer any guidance as to how I might resolve these problems.

          Many thanks


          • Matthew Petroff says:

            1. You should be able to avoid distortion without having to add empty space to the images using a combination of the haov, vaov, and vOffset parameters. Avoiding display of empty black space is a bit more tricky since this is dependent on both window size and zoom. Currently there are the minPitch, maxPitch, minYaw, and maxYaw parameters that limit where the center of the view can be set to; obviously, if this is set such that the black space is barely cut off at a specific zoom, zooming out will make the black space visible. It might be nice to add in parameters to set the maximum extents of the view instead of the maximum extents of the center, but it would be much trickier to implement than the current center limits.

            2. This appears to be the same issue that is described in issue #77. For some reason, iOS only works properly with progressive encoded JPEGs, and your images have standard JPEG encoding. WebKit doesn’t throw any errors and silently fails to properly display the image instead, making it difficult to write a proper check that can display a helpful error message. I guess I could write a check that sees whether or not the image is progressive and combine that with browser detection.

  29. Johno says:

    Hi Matthew,

    I’ve just started playing around with spherical panos and I found Pannellum. Thanks for the work to get this running. I’m always pleased to be able to use OSS wherever possible.

    It has been a very steep learning curve for me, but (after a couple of hours) I’ve managed to get a pano displaying.

    So my question is about the documentation. Pretty well everything I’ve found so far appears to assume that the reader understands how it all works and it just covers some detail. It would be nice to see a guide on how to getting the whole thing running from scratch. Is there anything like this in the pipeline?

    • Matthew Petroff says:

      It’s something I’ve been meaning to do for a while but haven’t really worked on. I would like to create a getting started tutorial and a much more complete example set that demonstrates how to use Pannellum’s various capabilities.

      • Johno says:

        That would be wonderful. I think better doco would open it up to more people, especially people like me who have no previous experience with this branch of pano photography. There are plenty of tutorials on Hugin for example to get you a nice pano file, but turning that into an interactive display on a website is a bit of a mystery.

  30. Driss says:

    I started working on a simple app that allows to taking measurements from panoramic pictures. I found Pannellum, and it was interesting. I just have a problem with yaw and pitch and I want to know how to make YAW value with 360° because now it shows 180° from right and left.

    • Matthew Petroff says:

      Being a sphere, modular arithmetic is used. Therefore, +180 degrees and -180 degrees in yaw refer to the same location, so the same value is always returned. I’m not really sure what you’re asking.

      • Driss says:

        Yes you are right! -180 and +180 refer to the same location. Instead of that, I need it to be +360 refers to 0, so yaw value will be always between 0 and +360. Is that possible?

  31. Johno says:

    Hi Matthew, it appears zoom in with the Shift key is much faster than the zoom out with the Control key. Do you see that too, or is it just my Mac?

  32. Thanks says:

    hi thanks for the good work,
    how can i convert yaw/pitch to xy coordinate (in pixels) of a panorama image?

  33. Pascal says:

    Hi Matthew. i salute you for the great work, keep up!
    i have a question. can we remove the distortion from th sides of the panormaric imges. like free from BI-AS


    • Matthew Petroff says:

      Pannellum uses an ideal pinhole camera model, so there are no “lens” distortions, just a plain rectilinear projection.

      • Pascal says:

        Can I remove the rectilinear projection and show it without distortions?

        • Matthew Petroff says:

          Rectilinear is what is normally considered “distortion free,” as distortion is normally considered to be a deviation from rectilinear projection.

      • Pascal says:

        I mean like equirectangular and not rectilinear

        • Matthew Petroff says:

          If you want to show an equirectangular images, you don’t need a viewer.

          • Pascal says:

            To make my idea clear, I want to extract the yaw and pitch on a 360 degree panoramic picture.
            Using the rectilinear viewer changes the value of yaw and pitch on the corners of the viewer even if it’s the same point.
            Example: point A at center = 180y/45p; when I move the point on the rectilinear view, this values changes continuously with 2 to 3 degrees.
            That’s why I need to use the viewer with 360/90 degree but showing an equirectangular image so the values wont change because of the distortion.

          • Matthew Petroff says:

            If you want an equirectangular projection, just use an equirectangular image, not Pannellum. I’m not sure how I can be any more clear. I’d recommend reading the Wikipedia articles on equirectangular and rectilinear projections. I consider this matter closed and will therefore not approve any more comments on the topic.

  34. Norbert says:


    is there any solution to run multires/ on windows? I have “windowserror: error 5 access denied” on line 94: subprocess.check_call([args.nona, '-o', os.path.join(args.output, 'face'), os.path.join(args.output, 'cubic.pto')]) with windows 8.1 . the output folder with cubic.pto gets generated.


    • Matthew Petroff says:

      I just tried it under Windows 7, and it works fine. Your error message suggests a permissions error, but since the output folder gets created, there must be an issue with nona. The only way I’ve been able to trigger that error message is by specifying a directory for the -n option instead of a full path to nona.exe. I would check to make sure you’re specifying the proper location for nona, e.g. python panorama.jpg -n "C:\Program Files\Hugin\bin\nona.exe".

  35. valerio says:

    Hi matt, hi eb, good job! Can I to put Pannellum on my DigitalOcean server? Is it okay a Linux Ubuntu 14.04 with LAMP or I need so? tks valerio

  36. Derek says:

    Thanks for the tip on…

    1) Removing the empty space from non full equirectangular images.

    Now that I understand that voav and voffset will not automatically hid the empty space from view, I have written short javascript function that dynamically changes the maxPitch according to the formula

    maxPitch = ((vaov+vOffset)/2)-(hfov/2)

    The javascript is in a loop and works nicely.

    2) Using progressive encoded JPEGs so that it Pannellum works on iOS devices. Problem resolved. Excellent.

  37. valerio says:

    Hi Matthew, hi everybody. Can you share examples of JSON files such as “example-cube.json”, “example-tour.json”, “example-video.json” with more configurations inside according JSON Configuration File Options? Thanks.

  38. valerio says:

    It works with my iOS app panorama. Now I try with frame by camera with Hugin or pano2vr; any suggestions or tutorial how get the frames? Thanks.

  39. Rolf Ris says:

    I just want to give Pannellum a try.
    If I understand correctly, I can locate Pannellum on my host-server and my equirect panopictures too.
    Then it is possible to load the pano with a simple URL?

    During searching around about Pannellum I have found this address:

    What do you think? Helpful?

  40. haustein says:

    Hi Matthew,

    Thanks for this tool. My problem is that I have no idea to integrate the hot spots like you have integrated in your example with the “Gallery”.

  41. Jianhua Wang says:

    Dear Matthew,

    I am trying the Pannellum; I like it very much.
    Just now I can browse my panorama page from a web server. But I want to know if I can view the panorama page by browser in local file system directly?
    If can, and how?

    • Matthew Petroff says:

      From the readme:

      Due to browser security restrictions, a web server must be used locally as well. With Python 2, one can use python -m SimpleHTTPServer, and with Python 3, one can use python -m http.server, but any other web server will work as well.

      Essentially, some sort of web server needs to be run locally; it doesn’t need to be anything fancy, so there are a plethora of options that work.

      • Jianhua Wang says:

        Dear Matthew,
        Actually, the way of using a web server is not convenient to my case. I have to browse the panorama page locally without web server.
        So, how I implement this? What part of code I need to care? Can you give some ideals or hints?

        Thank you very much.

        • Matthew Petroff says:

          Browser security restrictions prevent JavaScript from loading files from the local filesystem, which is why a web server is needed. There’s no way around it.

          • Jianhua Wang says:

            I am confusing, that I test other panorama viewer, such as KRPano, it use javascript too, found that the panorama page can be browsed in local file system. How do they work?

          • Matthew Petroff says:

            They don’t work with JavaScript. Only the Flash part of krpano can be used locally.

  42. wjhtinger says:

    What is the difference between the examples of cube and multires?
    If I just configure the “maxLevel” = 1 in example-multires.json, then the multires is equal to cube, right?

    • Matthew Petroff says:

      The effect will be the same, but different rendering code will be used. If you’re not using an image pyramid for the cube faces, you should use the regular cubemap mode. It’s more efficient as it use WebGL’s built in cubemap feature opposed to building the geometry from triangles.

      • wjhtinger says:

        How about the compare between equirectangular(example.htm) and cube(example-cube.htm), which is more efficient? Small size image should use equirectangular and big size image(>4096px) should use cube, is right?

        • Matthew Petroff says:

          There isn’t much of a difference as far as efficiency goes, but you’re right that equirectangular images should be limited to 4096px for better compatibility.

  43. json says:

    What if i want to create a hotspot on click or doubleclick?

  44. Pietro Toniolo says:

    Great work Matthew. Thank you.

    I am going to replace the flash-based panorama viewer on my site with your code. I tried to render some very large jpg files created with Hugin, with sizes like 8Mb, 11720×5860. Chrome 45 renders them correctly, but Firefox 40.0.3 crashes, usually when I try to move the cursor or when I go fullscreen.

    I have verified that with smaller files (like 1024×512) even Firefox renders the panorama correctly without crashing.

    Do you know of any limitations on file sizes or number of pixels affecting Firefox?

    • Matthew Petroff says:

      I’ve never had Firefox crash due to a large file, but crashes of this sort with WebGL tend to be graphics driver dependent (Chrome handles graphics drivers differently than Firefox). Regardless, I would not recommend using equirectangular images that big, as images larger than 8192px are only supported by ~50% of devices, while images larger than 4096px are supported by ~80%, and images smaller than 4096px are supported by virtually all WebGL capable devices. For large images, I would either use cubemaps (limit the cube faces to 4096px), or ideally Pannellum’s multires mode. The cubemap mode is easier to use, but the multires mode supports larger images and reduces load times.

  45. wangjh says:

    How do I generate the cube images? I have tested the and configuration.htm, but only generate multires images and configuration.htm only generate single image codes. Did I miss something?

    • Matthew Petroff says:

      You didn’t miss anything. Nothing in the Pannellum distribution generates cube maps as there are a plethora of existing utilities to choose from as cube maps are a standard format for both the panorama and video game development communities. Personally, I use the erect2cubic script from Panotools::Script.

  46. Do you have an elementary tutorial please?
    Step 1: Import your panorama jpg or bmp
    Step 2: …
    and so on?

    • Matthew Petroff says:

      I don’t having anything like that, sorry.

      • Bruce says:

        How about a wee bit of direction regarding the implementation of the program.
        I’ve unzipped the downloadable file. Now what?
        Do I put it all on a server? or just some files?

        • Matthew Petroff says:

          When using a release build, the only file that needs to be placed on a server is pannellum.htm (and your panorama image). In the simplest case, accessing will display yourimage.jpg in Pannellum assuming it is in the same directory on the server as pannellum.htm.

  47. Stefano says:

    Hi Matthew.
    First, really congratulations and thanks for the fantastic job you have been able to create! It’s very impressive!

    Into the website that I’m developing, I would like to create a preview of every panorama (equirectangular) loaded.
    This for lighten the load of the list of panorama available.
    I would like to automatically create an image of the initial view, can you give me some advice on how to make this using the Pannellum functions?

    Greetings and congratulations again.

    • Matthew Petroff says:

      The preview option allows for specifying a preview image that will be displayed before the panorama is loaded. As for actually creating the preview image, you’re on your own.

  48. tester says:

    Is there a way to stop the user panning 360 degrees? For example, if my panorama image is only 5000 pixels by 1000 pixels, can you limit the viewer to only pan the size of the image and not right up and down?

    appreciate your help

    • Matthew Petroff says:

      I’m assuming your panorama doesn’t extend to the zenith and nadir (giving image dimensions as an example doesn’t tell me much about the angular size). If my assumption is correct, you want to use the minPitch and maxPitch parameters to limit the angles the user can center the panorama at.

  49. Richard says:

    Hi there,
    Thanks for this great project. Actually, in internet explorer 11 and chrome 46, zooming with mouse wheel is a bit confusing and does not work very well. Is there fix available instead of just using the +/- buttons?

    Thanks in advance and good luck for your next work.

    • Matthew Petroff says:

      It’s been fixed in the development version, and the fix will be in the next release, probably sometime next month.

  50. valerio says:

    Hi Matthew, what is your server? Ram, transfer? I’m on digital ocean with a LAMP Ubuntu 14.04 on this gear:

    Memory 512 MB
    Processor 1 Core
    Transfer 1 TB

    It’s little for Pannellum?

    I’m thinking to switch to:

    Memory 1 GB
    Processor 1 Core
    Transfer 2 TB

    Thanks bye

    • Matthew Petroff says:

      Since Pannellum is purely static content, it doesn’t really matter what server you’re running.

  51. Hi Matthew,
    I’m having some trouble running any example that uses a .json config file. The error I get is ‘The file http://pmsdu.test/examples/example-cube.json could not be accessed.’ for the cube example. The file is in the location it is looking in.
    I have no problem running a basic equirectangular panorama locally.
    System is win7 64, using IIS manager for the local server ( and Chrome Version 46.0.2490.86 m.

    I can view everything ok on the web, but I must be missing something basic this end re. the local server.


    • Matthew Petroff says:

      Does anything print in your browser’s console (Ctrl+Shift+K in Firefox or Ctrl+Shift+C in Chrome)? If pannellum.htm is hosted in a different location, there could be a CORS issue.

      • Philip Hortin says:

        Thanks Matthew,

        Theses are the two errors I get from the console:
        GET http://pmsdu.test/examples/example-cube.json 404 (not found) standalone.js:79
        parseURLParameters @standalone.js:79
        (anonymous function) @standalone.js:97

        Uncaught SyntaxError: Unexpected token <
        request.onload @ standalone.js:58

        I uploaded the examples onto my web site and they work fine so no need to go any further, just thought I'd give you the details anyway.
        Thanks for a great program.

        • Matthew Petroff says:

          The browser returned a 404 error for the configuration JSON; I have no idea why that would happen unless the file was not actually there. The rest of the errors are due to a bug with the error handling that I just fixed (unrelated to why things didn’t work).

  52. Hi Matthew,
    I have a couple of hotspots in an basic equirectangular panorama.
    On PC the work great but looking at them on a mobile platform (iPad and Galaxy S4 mini) the hotspots float around over the image as you pan, pitch or zoom. There location on startup is incorrect as well.

    Is this just a WebGL issue, or can I do something to fix it.


  53. FabKzo says:

    Hi Matthew,

    I’m trying – with no success – to display hfov and vfov below my pano title. So far I only get static display with config.hfov, the best would be an adaptative refresh: is there a way to make it?

    • Matthew Petroff says:

      At the moment, not really.

      • FabKzo says:

        Well, I’ve succedeed ; I’ve add an ‘if’ for config.hfov in function render() of pannellum.js .
        Examples here
        Is it the good way to make it?
        I want to understand now why is there such scrolling jumps in pannellum 2.1.1 .

  54. Hi Matthew, thanks for making a great panorama viewer. Is it currently possible to do any of the following:
    Define a hotspot as static while the panorama rotates.
    Adjust the size of a hotspot.
    Insert my own hotspots.
    Load hotspot targets on top of the panorama, e.g. a graphic file or a video file, which could then be closed.
    Thank you.

    • Matthew Petroff says:

      None of these features are built in.

      • jayson says:

        Would you show an example how to load a scene without clicking the hotspot. Example I make a static button, (stays on place while the panorama rotates) and when I clicked it will jump to a specific scene using the sceneId. Thank you very much.

        • Matthew Petroff says:
          viewer = pannellum.viewer('panorama', {...});
          document.getElementById('button').addEventListener('click', function() {
  55. Anubhav jain says:

    Hi Matthew,
    How can I create barrel distortion in the panorama viewer?

  56. Hi Matthew,

    I am working on this project from quite long and I am now stuck with Drag n Drop functionality where I can use Drag n Drop to create hot spot to show images upon panorama like the Panorama of whole house where we can create a hot spot to show Kitchen.

    Can you help me prepare this Drag and Drop? Any idea, formula, or indication will be much appreciated.

    I am in urgent need of your help/suggestion.


    • Matthew Petroff says:

      I just added the mouseEventToCoords function to the API. Passing your mouseup event to this function will give you the location’s pitch and yaw, which should give you the information you need to create a hot spot in your JSON configuration file.

      • Christian says:

        I’ve tried to add the ‘mouseup’ event as string to mouseEventToCoords().

        var panm = pannellum.viewer(‘panorama’, json_data);

        I got an error: v is undefined in function ea(a) at this line: d = v.getCanvas();

        I think I forgot something, but I have no idea.

        My pannellum-version is 2.2.1.

        Thanks for help in advanced,

        • Matthew Petroff says:

          The API reference explicitly states that the argument should be a MouseEvent object, not a string.

  57. Mahi says:

    Hi Matthew,

    Great job! I really liked Panellum. It is very useful. I got my things done with the help of this. I am stuck with one thing which I am struggling from two days. I wanted a “Loading…” screen to be shown before the pano is loaded. The pano type is “multires”. I can see it for the cubemap pano but not for multires. Immediately when I click “Click to Load Panorama”, it takes some time to load the pano, which I want to avoid by showing “Loading..” Screen. Please guide me how can I achieve this.


    • Matthew Petroff says:

      It can’t be done. The first level of multires tiles are a few hundred kilobytes, tops, and are often closer to 100kB, or less. As a comparison, the average website these days is over 2MB. Except on a really slow Internet connection, loading a multires panorama should be almost instant. If you want to decrease load times, use a smaller tile size with the multires generation script, say 256 instead of the default of 512. Another option would be to manually resize the images in the 1 directory to make them smaller.

  58. Mad^Angle says:

    Hey Matthew,

    I love your work.

    I’m trying to load Pannellum on mobile with no success;
    if I open your site on mobile, Pannellum works fine.
    Is there any setting recommended for mobile use?

  59. Walter says:

    Thanks for the update and for step-by-step tutorial; Pannellum 2.2.0 is now more intuitive to use.
    In multires mode, is it possible to change the starting view of a tour, only changing the url?


    • Matthew Petroff says:

      Yes. If by “starting view” you mean where the camera is pointing, use the pitch and yaw URL parameters. If you mean which scene, use the firstScene parameter.

      • Walter says:

        Is it possible to choice the scene by passing this parameters into url of the browser? (not in the html code).

  60. Steve Busch says:

    Is it possible to trigger a function that opens up a modal or a pop up when you click on a hot spot?

    • Matthew Petroff says:

      Not at the moment.

    • enapupe says:

      I just did a major ‘quickfix’ for that.. It is something like that:

      $(“.pnlm-render-container”).on(“click”, function(e){
      var parentElement =;
      if(parentElement.tagName.toLowerCase() === ‘a’){
      // do some stuff with parentElement.href to check which hotSpot was clicked..

      Use at your own risk

  61. nitin kandpal says:

    Hi All,

    I am getting a random error. I am initializing the viewer with different panoramas from JS. The renderer sometimes works with the image and sometimes throws a WebGL error. I am using Mozilla browser.

    Please help.

    • Matthew Petroff says:

      If your images are different sizes, some of them are probably too big for your computer. If they’re all the same size, WebGL might be unstable on your computer.

  62. Vedran Vekić says:


    First of all – thank you for a great viewer, really simple, clear and gets the job done!

    I have a question regarding creation of Viewer:
    Is it possible to have many viewers on a page, and only have one of them loaded, and the other ones in the “preview image” state?

    I’m missing some functionality on the viewer for this. Something like .unload() or even .destroy() to eliminate the viewer entirely. Would this be possible?

    • Matthew Petroff says:

      You could set one to auto load and others to not, which would leave them in the preview image state. There’s currently no destructor function or way to unload a panorama, if that’s what you’re asking.

  63. Christian says:

    Hi Matthew,

    I have a question regarding the API. How to use the renderer methods like destroy()?

    My suggestion is to remove a pannellum viewer after updating the json parameterfile from DOM. After that I want to load a new instance of pannellum viewer with new params.

    This is my code to load pannellum viewer:
    url: url,
    data: data
    }).success(function (response) {
    // How to use destroy() method here for existing viewer?
    $.getJSON(response.jsonfile, function (json_data) {
    var panm = pannellum.viewer(‘panorama’, json_data);


  64. Rana Dakota says:

    Hi Matthew,
    Thank you for this awesome work. I was working with and I am getting error -n/-C:\Program Files\Hugin\bin\nona.exe is required on Python console.

    Below is the argument I am giving in my code.
    parser.add_argument(‘-n’ , ‘-C:\\Program Files\\Hugin\\bin\\nona.exe’ , default=’nona’, required=nona is None,
    metavar=’EXECUTABLE’,help=’location of the nona executable to use’)
    Can you please guide me through this.

    • Matthew Petroff says:

      I have no idea what you’re doing; you shouldn’t be modifying the Python code. You need to call from a terminal. This requires that either nona is on your path or it is specified as a terminal argument, e.g. python -n "C:\Program Files\Hugin\bin\nona.exe" pano.jpg.

  65. Dave says:

    Hi Matthew,

    Thanks for Pannellum, it’s proving to be really useful. I just have a question about the best way to load a new image. I want to be able to scroll through change to the next image on a button press. I’m currently reloading the viewer every time, which causes trouble with webGL loading too many things. Is it possible to reload the image in the same viewer?

    • Matthew Petroff says:

      As long as all the panoramas needed on a specific page are known beforehand, the tour syntax can be used (there’s currently no way to dynamically add a new panorama). There’s a `loadScene` API method in the development version that then allows the panorama to be changed.

  66. jignesh davara says:

    It’s great to work with

    I have installed it, and it works good

    but I have a question

    How do I get the required parameters pitch, yaw?

    Is there any tool to find them?

  67. Hua says:

    So I download the website image ( and uploaded to Imgur ( to test it out in Simple tutorial section (,
    and this is not working for some reason. Anyone could help me on this? Thanks.

    • Matthew Petroff says:

      It was blocked due to mixed content (the image had an HTTP URL, while the simple tutorial page has an HTTPS URL). The generated URL and iframe were correct, though. I updated the configuration generator such that this won’t happen again.

  68. Michael says:

    What a fantastic piece of software! Even my novice skills could get this up and running on my weebly page with about an hour of initial tweaking. Now it’s a breeze. You’ve made some great resource material, and I think I’ll be telling everyone I know about this.

  69. Uwe Krätzig says:

    Hi Matthew,
    Thank you so much for this great program! Everything works for me except parameter autoRotateInactivityDelay. I noticed you fixed this on April 22. The files of the latest Pannellum version 2.2.1 are dated March 17, so the fix isn’t contained in this release. Where resp. when can I get a Pannellum version with working parameter autoRotateInactivityDelay?

  70. Uwe Krätzig says:

    Thank you for this new version. Here are my results testing autoRotate:

    Notebook / Windows 7 / Firefox 47.0:
    Using mouse, rotation restarts as expected.
    Keyboard functions (cursor keys, shift, control) don’t work at all. After changing pitch with mouse, keyboard works again, but rotation doesn’t restart. Strange…

    Tablet (Microsoft Surface Pro 3) / Windows 10 / Firefox 47.0:
    After changing pitch or zoom via touchscreen, rotation usually starts again (not always).
    Keyboard behaves like on notebook.

    • Matthew Petroff says:

      There were some bugs; I think I just fixed them. I updated the previous link with the latest version.

  71. Uwe Krätzig says:

    In this latest version of pannellum.htm autoRotateInactivityDelay seems to work stable.
    But the “keyboard bug” is still there: Keyboard functions (cursor keys, shift, control) initially don’t work. After changing pitch with mouse, keyboard works again (and autoRotateInactivityDelay then works, too).

    • Matthew Petroff says:

      The viewer needs to be selected, e.g. clicked on, before it can see keyboard events; there’s no way around this.

  72. Uwe Krätzig says:

    Ah, I see. Thank you!

    Another question regarding parameters pitch and hfov: Omitting these parameters sometimes the initial display of my panoramas looks good (small or no black regions on top and/or bottom of panorama, “wide angle zoom”), but sometimes I have to experiment with pitch or hfov to get rid of these black regions and optimize zoom. Is it possible to automatically “optimize” the initial display of the panorama when parameters pitch and hfov are omitted (instead of constant default values hfov=100 and pitch=0)? Or something like pitch=automatic, hfov=automatic?

  73. Paul says:

    Thanks for a great viewer.

    I have one question:
    Suppose I load an image at lat-lon 5.123, 51.123

    How can I calculate the coordinates of a hotspot that points to an image at alt-lon 5.124, 51.124

    The idea is that the user can click on that hotspot, opening the next image (having also hotspots of images nearby)



  74. Hi, Thank you for creating this amazing tool. I’ve been playing around with it, and it’s a lot of fun.

    Is there a way to animate to a hotspot using javascript and not mouse events?
    I tried something like myViewer.getRenderer.render({“pitch” : 30}), but that just brought up an empty screen.

  75. Can you give (to us who are more photographers than programmers) a little guidance on non-fullscreen screen width?

    I take it that when I load a multiresolution pano as standalone it loads at full screen width (and full height except the browser menus) even before I go into full screen mode. Very pretty! But if I do it as API I have to specify a fixed size (e.g. #panorama { width: 600px; height: 400px; } ). Is that right?

    I.e. I’m looking to fill the (normal browser) window when doing a multiresolution pano with hotspots. Can I, and can I do it standalone? I think that is to ask, can I put hotspots in the .json file?

    Hope that makes sense. OSX 10.11, Firefox 47, Pannellum from spring 2016. Thanks for a great tool!

    • Matthew Petroff says:

      Take a look at the multiresolution and hot spots examples. If you look at the standalone version for each example, you’ll see that everything is specified in a .json file. The API is only necessary for interacting with external code.

      • Robb Campbell says:

        Great– thanks. I had noticed that the hotspots and multires were never together; I’m glad to hear that was just a coincidence. I’ll try again.

  76. Muruli says:

    In Pannellum, is it possible to use an image for a hot spot or change the style of a hot spot?
    your faithfully

    • Matthew Petroff says:

      If you use the API version, you can override the CSS classes related to hot spots, e.g. .pnlm-hotspot.

  77. Jesse says:

    Hi Matthew.
    First, thanks for the great panorama viewer!

    Fish-eye and little planet effect I want to achieve by modifying your Fragment shader, the Equirectangular should be able to, but the cube is impossible, ask you what you accomplished?

    float phi = atan((y * costheta + u_f * sintheta) / root – u_theta);’,


  78. Frank says:

    Hi, first of all, excellent work! Now, I would like to know if there is a way to make that the action click+hold+drag+release smoother? Thanks in advance!

  79. Jesse says:

    Hi Matthew,
    I try to add WEBVR, vrDisplay orientation and fieldOfView is need to be converted to a Matrix, to render the panorama. Now yaw, pitch, roll, and focal length respective can’t seem to render the left eye and right eye, it looks very strange with my HTC VIVE Rift.

    Can you give me some advice?

    I refer to this case:




  80. Jesse Wang says:

    Hi Matthew,
    There is a problem when on the phone or Tablet while browsing the panorama, roll is not zero, hotspots positioning errors.

    Hotspots position requires the roll function?


  81. Frank says:

    Hi Matthew,

    I was wondering, is there a way to pause autoRotate and then start autoRotate up again using JavaScript. Thanks in advance.

    • Matthew Petroff says:

      There are startAutoRotate and stopAutoRotate functions in the development version that can be used (they’re not in a release yet).

  82. Erik Saar says:

    Hi! Is there a way to in the info hot spots do a line break and have bold text. Like a head line and info text below.

    • Matthew Petroff says:

      No, there isn’t. HTML is escaped to prevent Pannellum from being used to execute DOM-based XSS attacks.

      • Sergio Ccahuana Giraud says:

        Hi! First of all…thank you for this amazing software…As Erik, I’m also interested to include some kind of format and moreover to display an image when hovering a hotspot…

  83. Hi Matthew,

    Still enjoying. I believe this is not a duplicate: Do you have or plan a keystroke to toggle all overlays (i.e. the user’s hotspots plus your zoom/fullscreen controls) off and on? A bit like the tab key in Photoshop. This would be pretty and powerful. Thanks!

    • Matthew Petroff says:

      I don’t have any plans for such functionality. I don’t think it would be obvious to user and could cause confusion if accidentally pressed.

  84. Robb Campbell says:

    Thanks; these are good considerations. But I had assumed an “OK / don’t ask again” dialog, or better yet a button with hovertext. Without togglable overlays or a sequence of images (before/after etc.) the functionality gets boxed in pretty quickly. The tour links are just the right idea, but only for one view of different places and not differing views of one. Perhaps in the future.

  85. Hi Matthew,

    The possibilities of Pannellum intrigue me. I have a weekly comic strip called Luckyzilla, and I have a strip coming up that was made specifically to be uploaded to Facebook as a 360 panorama. I realize that could be quite limiting for my audience which may not have Facebook and would want to implement Pannellum on for such strips. I use GoDaddy to build my site – would your software….language….plug-in, or whatever it’s called, be compatible with GoDaddy’s Website Builder?

    Best wishes for your current and future endeavors.

  86. Is there a way of changing the loaded image from a hot spot,
    like a tour, but our ‘tours’ consist of 18000 images (when only the next few ever need to be accessed)

    I’ve managed to get hot spots on and detect them being clicked, and I’ve almost managed to change the image, but I think I’m creating a new instance of the viewer, rather than just updating the image.

  87. Mike H says:

    Hi Matthew!

    I was pleased to learn about Pannellum this weak from an acquaintance. It’s so much easier (and performs better) than panosalado.

    Two questions:
    1. How do I make the hot spot title tooltips always visible?
    2. How can I change the icon used for hot spots? (They are too small when viewing in fullscreen on a PC.)

    • Matthew Petroff says:

      1. This isn’t directly supported, but adding div.pnlm-tooltip span {visibility: visible !important;} should accomplish it.

      2. To change all the hot spots, you need to override the default .pnlm-hotspot CSS definitions. The Git development copy includes support for the cssClass parameter on hot spots that allows one to override the CSS that is used to style specified hot spots.

  88. Mike H says:

    I just wanted to add that in the browsers on my phone, a Nokia Lumia, the panorama would not render when the cube map images were 1600x1600px. On the other hand 1024x1024px worked fine. Not sure why this is the case. I think the error message said something about not having the correct WebGL version. Sorry I didn’t take a screenshot.

  89. Roberto Scanavino says:

    I would need that the panel would work on IE 10, just an internal viewer.
    First page at works with IE 10, but the link to results in ““Your browser does not have the necessary WebGL support to display this panorama”.
    Can it work?

    • Matthew Petroff says:

      No. IE10 does not support WebGL. The panorama that works is using the fallback CSS 3D transform-based renderer, which only works for cube maps. Microsoft stopped supporting IE10 earlier this year, so I’d highly recommend using a browser that receives security updates.

  90. Marcelino A. Mosquea S. says:

    I’m developing a website (I’m the designer, I’m working with other guy, he is the programmer) we are using your API, and it works really great! but I have a problem… I have some issues in this computer, if I run Chrome with hardware acceleration I get some slowdowns, so I turn it off… Without H.A. I can’t see the panos in my site, but here they seems to work just fine… what do you think is the problem??

    • Marcelino A. Mosquea S. says:

      by the way… the error is “your browser does not have the necessary webgl support to display this panorama”

      • Matthew Petroff says:

        You’re disabling WebGL by turning off hardware acceleration. Equirectangular panoramas require WebGL, which is why you get the error. Cube map and multires panoramas have a fallback renderer that uses CSS 3D transforms, which is why the panorama on this page still works.

  91. Angel P. says:

    Hello Matthew

    I am using your awesome api on my site and i have to say that , it works really great!I have a question for you!I am trying to disable the mouse wheel zoom so i set “mouseZoom” to false but the mouse wheel keeps zooming.Is there something I’m doing wrong?

    • Matthew Petroff says:

      I’m guessing you’re using the 2.2 release. The feature was added after the last release, so it’s currently only in the development copy.

  92. Richard says:

    Hi Matthew,

    your panorama viewer looks really great. You mentioned earlier, that a web server is required due to javascript can not load images locally from files. Now I wonder, how OpenLayers can load images as png from the local file system without any problems? Another WebGL pano viewer is available at able to read from local files. What is the reason Pannellum can not do this? On the other hand, is there any way to “embed” an image directly into the javascript file f.i as base64 coded?

    Best regards,

    • Matthew Petroff says:

      It’s dependent on exactly how the image is loaded and is not consistent across different browsers. For example, the three.js demo you mention works in Firefox but not Chrome; Pannellum’s loading method could probably be tweaked for this, but it would bring a slew of bug reports from people who try to use a different browser. As for OpenLayers, the JavaScript is just creating <img> elements, not actually loading the image, which is why it works (this method can’t be used with WebGL).

      • Richard says:

        Thank you for explanation. How about to embed the image directly into the html/js file?

      • Richard says:

        Dear Matthew,

        I’d like to circumvent the problem, but I am not an javascript expert. How about to create a tag not visible and get the image object out of it? What I have to change in the code to do so?

        • Matthew Petroff says:

          No matter how you load the image, it will have bad taint, so it can’t be used with JavaScript, in general. If you want to use a data URI, it just needs to be specified as the image URL. The protocol check that produces the error message when loading images from the local filesystem can be disabled by commenting out (or deleting) the check at the bottom of src/standalone/standalone.js.

  93. Please advice the price if we need to use this for commercial purposes. We can even agree on on standard monthly support cost and cost for enhancements. We intend to use this for Real Estate Commercial places like Mall and Hotels to provide 3d Virtual tour like Mall navigation system. I guess we will need to use 3D cameras also.

    • Matthew Petroff says:

      It’s free, even for commercial purposes. You just need to comply with the license, which essentially amounts to leaving the attribution statement in the code.

  94. This tour looks great. Does it allow the view direction to be set based on the link that gets you to that scene? For example, if I had three 360 images representing a hallway:

    A B C

    …when I click from A to B, it should show B facing EAST. When I click from B to C, it should should C facing EAST. Then, if I click from C back to B, it should be facing WEST.

    The demo on your site did not do this, but I thought I’d ask if it was possible. Thanks!

  95. Marko says:

    Hi, awesome pano viewer. One question. I have some panorama images in png format and I was wondering if it is possible to also show the alpha channel. By default, when the pano is loaded, everything that has an opacity of 0 is rendered black.

  96. Xbo says:

    Hi Matthew,
    I have chosen to make only one config file for all my panos, they all are “multires” type, they all have the same “path”, the same “fallbackPath”, same “extension”, same “tileResolution”, lots of my hotspots have the same “type” and same “targetYaw” (sameAzimuth).
    It would be good if we could put all those parameters in the “default” section.
    Pannellum has become a very good pano viewer; thanks a lot Matthew!

    • Matthew Petroff says:

      The properties you are referring to are all subproperties. Merging them into the default configuration would make the configuration loading code needlessly complicated, so I have no intention of adding this feature.

  97. lancelot says:

    Hello, can we make hot spots in a 360 video mode?
    Thank’s a lot for your job!

  98. Louis says:

    Really like what you have done. Just started to experiment with it.
    I found something strange. When I try to load a preview through the iframe it works. Doing it through the API it also works. However when doing it through a json file the preview does not show (defined the preview in the json file)
    The rest of the config in the json works fine. Panorama loads, title, author and hot spots are shown.

    As the other methods show the preview image I know it is available and the link is Ok.

    What might be the cause for this?

    • Matthew Petroff says:

      Do you have an example I can take a look at? It works fine for me.

      • Louis says:

        Thanks for solving it so quickly. Changing the Absolute URLs (i.e. starting with `http://`) to relative URLs solved it. Good to know that it is already fixed in code.

        An idea for a feature I would like to see is to have different numbers (or letters) as a hotspot. This would allow to create a legend beneath the panorama explaining (in more detail) about the hotspot.

        • Matthew Petroff says:

          This can be done by setting different cssClass parameters for each hot spot, and then defining corresponding CSS classes to style each hot spot differently.

  99. Leo zhang says:

    Hi Matthew,
    I have use ‘’ to generate the multires type, and I can successfully load the panorama viewer on desktop’s and mobile devices’ browser, and also in the iphones’ wechat browser, but I fail to open the viewer on android’s wechat browser. I don’t know why this happen?

  100. Jens Menke says:

    Hello Matthew,
    Thanks a lot for this viewer.
    I have a little problem with Google Chrome.
    In FF and IE everything is fine. In Chrome I look to the floor.
    What can it be?

  101. Johann says:

    Hello Matthew.
    (Translation google French -> English, Thank you)
    I just discovered your Pannellum app.
    I test your solution and I have an error message on the image. (I’m local to test)
    “The File … could not be accessed.”
    This image is the “alma.jpg” image of your site.
    What part could I watch or what to change please?
    Thank you for your reply and thank you for your work.

    • Matthew Petroff says:

      Use your browser’s developer tools. The developer console should show a more detailed error. It’s probably getting a 404 error, and the developer console should show you what URL it is trying to access.

      • Johann says:

        Thank you Matthew.
        I look and try to find.
        It does not actually find the file.
        But it shows me a link and when I click, it shows me the image without problems.
        Is it ok for me to be on my pc locally?
        Thank you and good day to you.

        • Matthew Petroff says:

          As mentioned in the readme, a web server must always be used, even locally, due to browser security restrictions.

  102. Rick says:

    Hello. Wonderful application you have Matthew. I am noticing an issue wherein the hotspots locations are off by quite a bit when viewing the images in fullscreen. I’m noticing it in every image, including all the examples here on your site. Is there something that I am possibly doing wrong, or is this an unaddressed issue?

    • Rick says:

      I’ve noticed now that it is my browser. The image becomes stretched, but only to the right, and only when viewing in fullscreen with Safari. I tested it in Chrome, Firefox, and Safari. I will troubleshoot and let you know if I find any fixes.

      • Matthew Petroff says:

        The behavior suggests that the resize event isn’t firing. What version of Safari are you using? I can’t reproduce the issue on Safari 9.1.3.

  103. George says:

    Hello Matthew, this Pannellum seems to be beautiful piece of work. I am considering buying a Ricoh Theta S. Reading through the product review (, I wanted to try the sample photos with Pannellum but I failed:
    There are several sample files, I tried them in Edge, Chrome, and FF, all give the same error message: The file ‘…’ could not be accessed. I also tried the API sample from your Example page, locally saved both the HTML and the jpg next to one another. Same result. Is this a bug, or did I miss something? Thanks!

    • Matthew Petroff says:

      The link you give as-is, is failing due to mixed content—you can’t load Pannellum over HTTPS and the image over HTTP. Changing to the HTTP loading of Pannellum, it still fails, because the server hosting the image in question doesn’t support CORS, which is required for loading images from a different domain. Both these errors and logged to the browser’s developer console. Theta S images work with Pannellum; most of the images in the examples section of were shot using one.

  104. Uwe Krätzig says:

    Hi Matthew,
    I would like to display local panoramas without starting a local web server. Possible solution could be FileReader API. User selects the panorama via input type=”file”, FileReader gets image as binary string (readAsBinaryString) which is displayed by Pannellum. Would you consider to upgrade Pannellum API so that in addition to configuration parameter “panorama” (URI of panorama) a string containing the image can be passed to Pannellum, for example via new parameter “panorama_string”?

  105. Mike says:

    Hi Matthew,
    Great work on this project. Thank you for the continued efforts.

    I am trying to export the viewer canvas to an image using canvas.toDataURL(). I am returned a data url, but the image is always black. I’ve tried png as well as jpeg and still no luck.

    I was wondering if you’ve worked with exporting the current scene to an image on the client. Any guidance would be greatly appreciated.

    Thanks again!

    • Matthew Petroff says:

      I’d recommend reading this Stack Overflow response for a detailed explanation as to why you get a black image. The short answer is that the Pannellum’s WebGL context has preserveDrawingBuffer set to false because it’s faster, which means the render buffer is cleared as soon as the render function returns. However, you can grab the rendered frame the same way that it’s done for fading between tour scenes:

      viewer.getRenderer().render(viewer.getPitch() * Math.PI / 180, viewer.getYaw() * Math.PI / 180, viewer.getHfov() * Math.PI / 180, {returnImage: true});

      where viewer is a Pannellum viewer instance.

  106. Robert Campbell says:

    Thanks for the continued improvements. I love the custom hot spots and custom controls.

    I’m a little over my head here, but can I place a custom hot spot at an absolute position on the screen? Would I use the CSS to place it there (like the custom controls example), and omit the pitch and yaw?

    • Matthew Petroff says:

      There’s no way to place hot spots in an absolute position by default. You have the right idea about modeling something like this on the custom controls example. I assume you want these to be specific to certain scenes. You can subscribe external code to the scenechange event (using viewer.on('scenechange', yourfunction), where viewer is a Pannellum instance); Pannellum will then call yourfunction with the new sceneId as an argument, which would allow you to display the appropriate absolutely positioned hot spots.

  107. sam says:

    I get this message.
    “this panorama is too big for your device! it’s 10752px wide, but your device only supports images up to 8192px wide. try another device”
    It works on Microsoft Edge but not in Chrome browser. What is the solution ?

    • Matthew Petroff says:

      Scale the image down to 8192px or convert it from an equirectangular image to a cube map or Pannellum’s multires format (or use a device/browser combination that supports 16384px wide WebGL textures).

  108. Martin says:

    Hello Matthew,

    Thanks for Panellum, I love it!
    I have two (maybe three) tasks I want to accomplish and dont know how to…

    1. I want to put a static image in the lower right corner of every panorama (a floorplan for example), how could I achieve that?

    2. in a tour I want a small preview picture of all the other rooms (read “scenes”) in the lower part of the panorama, how could I achieve that?

    (3). I Created my last tour via editing the json file which is quite labourius and time consuming, is there anywhere a kind of website or script to purt on my (internal) webserver, together with the panos I like to use and then create the hotspots via a web-gui?

    Can you (or anybody) give me some pointers or solutions on how to achieve that?

    Thank you for all your work, its really amazing what a wonderful bit of software you provide for all of us.

    cheers from germany

    • Matthew Petroff says:

      1. If you use the API, you can overlay other content over the panorama like is done in the custom controls example.

      2. Again, you could overlay preview images using the API. Furthermore, the API can be used such that clicking on the preview changes the scene.

      3. There’s currently no GUI (nor any immediate plans to create one).

  109. Freddie says:

    Hi Matthew,

    I was wondering if it is possible, when viewing Pannellum (iframe or fullscreen)
    on your mobile device.

    – have the VR (single lens mode) enabled by default (instead of the compass-mode, where you need to point with your finger)

    – change the background of the “click to load panorama” …

    Kind regards

    • Matthew Petroff says:

      Setting the orientationOnByDefault parameter to true will use the device’s IMU by default; I assume this is what you mean by “VR.”

      The background is set using the .pnlm-container CSS class’ background property, so you can override it with your own CSS if you create the viewer using the API.

  110. Martin Cheng says:

    Hi Matthew,

    I have a question. It is possible only config json file to use two 180 photos in Pannellum (iframe example) ?
    Because I only have a 180 cam.

    Thanks for your help.
    Best Regards

    • Matthew Petroff says:

      Partial panoramas are supported, if that’s what you’re asking.

      • Martin says:

        I resolved my issue. I have the other issue, my chrome auto updated to 57.0.2987.110 which can’t load the examples of “” except “Multiresolution panorama” example.

        The error is “Your browser does not have the necessary WebGL support to display this panorama”.

        Does it my PC problem?

        • Matthew Petroff says:

          WebGL isn’t working in your browser; the multiresolution example (and the cube map example) have a fallback CSS 3D transform based renderer, which is why they still work. Chrome 57 works fine for me. I suspect the WebGL test page won’t work for you either:

  111. Edwin Benavente says:

    Hi Matthew, I have an issue trying to use cube map or multires (please see link: It looks like there is a problem with the stitching or something, that happens to me on the pannellum site was well. I use the cube feature because I have users getting the “Your browser does not have the necessary WebGL support to display this panorama” error on their browsers. So I changed the configuration to use cube maps and I’m getting those stitching issues. Do you thin you can help me?

    • Matthew Petroff says:

      That looks like an issue that sometimes manifests itself in the CSS 3D transform based fallback renderer when WebGL isn’t working. It can be rather finicky at times on some browsers / devices, and I haven’t figured out a way to fix it.

  112. Hi Matthew,

    I’m really New this 360 stuff and I’m getting the “File Too Large” error while viewing on a mobile .
    I don’t really understand how to use to create the multi-res files require to display large files on a mobile device.

    When I run it on my MAC I get the following error

    Freds-MacBook-Air:Desktop fred$ python
    Traceback (most recent call last):
    File “”, line 30, in
    from PIL import Image
    ImportError: No module named PIL
    Freds-MacBook-Air:Desktop fred$

    Hope you can point me in the right direction.



    • Matthew Petroff says:

      Per the comment at the top of the script, the Python Pillow package is required (Pillow is a fork of PIL). You’re getting an import error because Pillow isn’t install (or isn’t in the Python path). You’ll also need nona from Hugin.

  113. Steven Kan says:

    Hi Matt,

    Great piece of software. Thanks!

    I’ve discovered some unexpected behavior on older iOS devices. I am attempting to display 360 degree equirectangular JPGs in an iframe, and my iPad 4 displays the “Your browser does not have the necessary WebGL support. . .” error if both of the following are true:
    1) The panorama is approx. 4000 pix wide, and
    2) Panellum is loaded inside an iframe greater than 1024 pix wide:

    So if the iframe is declared as 800 pix wide, I can load pannellum with a 4000 x 2000 pixel jpg.

    If I load pannellum in an iframe declared with a width of 1025 pix, it fails.

    If I load pannellum by itself in separate windows, e.g. _not_ an iframe, the 4000 x 2000 pixel jpg works fine.

    I’ve put up a test page, here:

    The 1545pix-wide iframe works fine on other platforms I’ve tried, e.g. all desktop browsers, an iPhone 5s, and iPhone 6s. It only fails on the older iPads.

    Oddly, the failing iPad and the working iPhone 6s report the same capabilities on the WebGL test report. The only differences are the “unmasked vendor” and “unmasked renderer.” All other reported info is identical between the two iOS devices.

    Do you still have no iOS devices on which to test? Would you accept donations to buy one or more? I’d be willing to donate a few dollars to the cause, as pannellum will likely save me a few dollars vs. a commercial platform.


    • Matthew Petroff says:

      I can reproduce this on the one iOS test device I have, an iPhone 5c. It seems that the maximum supported canvas width is 2048px (1024*2, since it’s a retina display), with larger sizes not working. However, the device erroneously claims to support render buffers up to 4096px, which means this can’t be preemptively checked. Since this results in a rather distinctive WebGL error, though, I just added a check for it that cuts the canvas size in half when it happens. This fix is a bit of a kludge, but it works well enough and is better than not displaying the image at all.

      For the moment, the one iPhone I have (which was sent to me by a company who wanted me to test under iOS) seems to be sufficient for iOS testings, but donations are accepted—there’s a donate link on the downloads page.

  114. Dominik Eichenlaub says:

    Hi Matthew,

    I try to use Pannellum in an offline file-based webpage. Meaning all files ar stored on an simple harddisk. This works fine in Firefox but not in Chrome 57 or IE 11. I always get an error, that the file could not be accessed. Like in other posts it has to be a CORS problem.

    «XMLHttpRequest cannot load file:///H:/TEST//scans/63.png. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.»

    Do you have any idea how I could fix this without uploading the files to an webserver? I would be great if you can help me!

    Thanks in advanced!

    • Matthew Petroff says:

      You can run a local web server; local file access is restricted due to browser security restrictions, as mentioned in the readme, so there’s no real way around it.

  115. Ricardo says:

    Hi Matthew,

    First, congratulations for this great software!

    I was testing it under Safari and Chrome and everything works great, but in Firefox I get an error telling that the image is too large. Image is an equirectangular 8704px wide and FF says that only up to 4096px width are supported, even in the same hardware! Anyways I wanted to ask you if there is any way of knowing in advance the maximum allowed width, as I can serve the image scaled down to that limit to avoid the error.

    Thanks in advance!

    • Matthew Petroff says:

      The maximum image size is set by some combination of the hardware, drivers, and browser. I’ve seen different browsers on the same computer report different maximum supported texture sizes before.

      You can test for the maximum supported image size in a similar way to how Pannellum does it:
      var canvas = document.createElement('canvas');
      var gl = canvas.getContext('experimental-webgl');
      var maxWidth = gl.getParameter(gl.MAX_TEXTURE_SIZE);

      The other way around this is to use Pannellum’s multiresolution format, which tiles the image such that it loads faster and is supported on virtually all WebGL capable devices; it’s more work to set up, though.

  116. Hello Matthew!
    How I can expand viewer to full screen after its creation?
    I tried to call toggleFullscreen(), but this method only restores to normal view.
    I tried this:
    var viewer = pannellum.viewer(‘museum’,{…});
    I tried called that with timeout – not happened.
    Where did I make mistake?

    PS Thanks for your project! It’s really great!

    • Matthew Petroff says:

      If I’m understanding you correctly, you’re trying to call viewer.toggleFullscreen() using setTimeout. This won’t work because browser security restrictions only allow JavaScript that is directly initiated by the user to enter fullscreen, e.g. clicks handler.

      • Yes, you understand me correctly.
        So, how can I load into fullscreen mode after image loading? I can do that if browser security JavaScript initiated fullscreen mode without user?

        • Matthew Petroff says:

          The only way to enter fullscreen mode is to call toggleFullscreen() on a click event handler.

  117. Darius says:

    Hi Matthew,

    I love this thing, pretty awesome good job.
    Is it possible to define different custom hotspot styles?! E.g. I have 3 hotspots in one scene but for each I would like to use a custom image. How could this be done?


  118. Marin Braun says:

    Hi Matthew,

    Thank you for this awesome script! When I mark a hotspot and give it a hyperlink, is it possible to open that link in the same window? Tried a lot but nothing really worked. I managed to open the link in a separate window but not in the same.
    Can you help me with this?

    Thanks Marin

    • Matthew Petroff says:

      The only way to do this without modifying the source code would be to set a custom click handler using the clickHandlerFunc hot spot parameter and have that handler set window.location. The link target is set to _blank, which opens links in a new tab, because the user would lose his or her place in the panorama / tour if the same window was used.

  119. Marcello Colombo says:

    Hi, is it possible to show the fixed hotspot point in the div “pannellum” with label: “next video”?

  120. Dami says:

    Hello Matthew,
    You’ve done a really great job with Pannellum, and it works fine with our project. I’ll like to ask if there’s a way I can use my 360 photos with Google Cardboard on mobile phones.

  121. Folu says:

    Hello Matthew,
    You’ve done a really great job with Pannellum, and it works fine with our project. I’ll like to ask if there’s a way I can create a hot spot whereby when I click on it, it will show up a media file like image or video on the panorama. Also, is there a way a hot spot can have a hyperlink feature?

    • Matthew Petroff says:

      For displaying something custom, you should create the viewer using the API and then use the clickHandlerFunc and clickHandlerArgs hot spot configuration parameters to trigger a custom function on click that does what you want. Hyperlink support is built-in and is activated using the URL configuration parameter.

  122. Diego Lopes says:

    Hi Matthew,

    So, I’m trying to use this app library, but I’m facing the follow error. Using an image in the site like, it’s working fine. If I put the same image in my local machine to do tests or put it in other site, I’m facing the error that the image could not be accessed. Do you know what is happening?

    Thanks in advance.

    • Matthew Petroff says:

      Your browser’s developer tools should tell exactly what’s happening. If you’re using a local file, you need to you a local web server as well, since browsers block loading files from the local filesystem; this is documented in the README. If you’re trying to load images from a different domain than the page you’re loading them from, it’s probably due to a CORS error; again, your browser’s developer tools will tell you.

  123. Steffen Schmidt says:

    Hi Matthew,

    Outstanding, elegant piece of work!
    Just recently I added Pannellum to a WordPress Project – worked like a charm (almost needless to say: without any Plugin hassle/conflicts).
    Thank you very much!

    Keep up the great work!