## File: README.md # Pannellum [](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml) [](https://doi.org/10.5281/zenodo.3334433) [](https://doi.org/10.21105/joss.01628) ## About 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 21kB gzipped, and then embedded into pages as an ``. A configuration utility is included to generate the required code for embedding. An API is included for more advanced integrations. ## Getting started ### Hosted examples A set of [examples](https://pannellum.org/documentation/examples/simple-example/) that demonstrate the viewer's various functionality is hosted on [pannellum.org](https://pannellum.org/). This is the best place to start if you want an overview of Pannellum's functionality. They also provide helpful starting points for creating custom configurations. ### Simple tutorial and configuration utility If you are just looking to display a single panorama without any advanced functionality, the steps for doing so are covered on the [simple tutorial page](https://pannellum.org/documentation/overview/tutorial/). Said page also includes a utility for easily creating the necessary Pannellum configuration. ### Local testing and self-hosting If you would like to locally test or self-host Pannellum, continue to the _How to use_ section below. ## How to use 1. Upload `build/pannellum.htm` and a full equirectangular panorama to a web server or run a development web server locally. * Due to browser security restrictions, _a web server must be used locally as well_. With Python 3, one can use `python3 -m http.server`, but any other web server should also work. 2. Use the included multi-resolution generator (`utils/multires/generate.py`), the configuration tool (`utils/config/configuration.htm`), or create a configuration from scratch or based on an [example](https://pannellum.org/documentation/examples/simple-example/). 3. Insert the generated `` code into a page, or create a more advanced configuration with [JSON](https://pannellum.org/documentation/reference) or the [API](https://pannellum.org/documentation/api/). Configuration parameters are documented in the `doc/json-config-parameters.md` file, which is also available at [pannellum.org/documentation/reference/](https://pannellum.org/documentation/reference). API methods are documented inline with [JSDoc](https://jsdoc.app/) comments, and generated documentation is available at [pannellum.org/documentation/api/](https://pannellum.org/documentation/api/). For the standalone viewer, configuration parameters are preferably specified using a location hash instead of a location search query, e.g., `pannellum.htm#panorama=...` instead of `pannellum.htm?panorama=...`, since this does not unnecessarily send the query parameters to the server. ### Using a minified copy For final deployment, it is recommended that one use a minified copy of Pannellum instead of using the source files in `src` directly. The easiest method is to download the most recent [release](https://github.com/mpetroff/pannellum/releases) and use the pre-built copy of either `pannellum.htm` or `pannellum.js` & `pannellum.css`. If you wish to make changes to Pannellum or use the latest development copy of the code, follow the instructions in the _Building_ section below to create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`. ### Using `generate.py` to create multires panoramas To be able to create multiresolution panoramas, you need to have the `nona` program installed, which is available as part of [Hugin](http://hugin.sourceforge.net/), as well as Python 3 with the [Pillow](https://pillow.readthedocs.org/) and [NumPy](https://numpy.org/) packages. The [pyshtools](https://shtools.github.io/SHTOOLS/) Python package is also recommended. Then, run ``` python3 generate.py pano_image.jpg ``` in the `utils/multires` directory. This will generate all the image tiles and the `config.json` file in the `./output` folder by default. For this to work, `nona` needs to be on the system path; otherwise, the location of `nona` can be specified using the `-n` flag. On a Unix-like platform, with `nona` already on the system path use: ```bash $ cd utils/multires $ python3 generate.py pano_image.jpg ``` where `pano_image.jpg` is the filename of your equirectangular panorama. If `nona` is not on the system path, use: ```bash $ cd utils/multires $ python3 generate.py -n /path/to/nona pano_image.jpg ``` For a complete list of options, run: ```bash $ python3 generate.py --help ``` To view the generated configuration, run: ```bash $ cd ../.. $ python3 -m http.server ``` This goes back to the root directory of the repository and starts a local development web server. Then open http://localhost:8000/src/standalone/pannellum.htm#config=../../utils/multires/output/config.json in your web browser of choice. ## Bundled examples Examples using both the minified version and the version in the `src` directory are included in the `examples` directory. These can be viewed by starting a local web server in the root of the repository, e.g., by running: ```bash $ python3 -m http.server ``` in the directory containing this readme file, and then navigating to the hosted HTML files using a web browser; note that the examples use files from the `src` directory, so **the web server must be started from the repository root, not the `examples` directory**. For the `example-minified.htm` example to work, a minified copy of Pannellum must first be built; see the _Building_ section below for details. Additional examples are available at [pannellum.org](https://pannellum.org/documentation/examples/simple-example/). ## Browser Compatibility Since Pannellum is built with web standards, it requires a modern browser to function. #### Full support (with appropriate graphics drivers): * Firefox 40+ * Chrome 41+ * Safari 9+ * Edge 12+ The support list is based on feature support. As only recent browsers are tested, there may be regressions in older browsers. #### Not officially supported: Mobile / app / web frameworks are not officially supported. They may work, but they're not tested and are not the targeted platform. ## Translations All user-facing strings can be changed using the `strings` configuration parameter. There exists a [third-party respository of user-contributed translations](https://github.com/DanielBiegler/pannellum-translation) that can be used with this configuration option. ## Building The `utils` folder contains the required build tools, with the exception of Python 3.2+ and Java installations. To build a minified version of Pannellum, run either `build.sh` or `build.bat` depending on your platform. On a Unix-like platform: ```bash $ cd utils/build $ ./build.sh ``` If successful, this should create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`, relative to the root directory of the repository. ## Tests A minimal [Selenium](https://www.seleniumhq.org/)-based test suite is located in the `tests` directory. The tests can be executed by running: ```bash python3 run_tests.py ``` A Selenium-driven web browser (with a Chrome driver, by default) is created, and screenshots are generated and compared against previously generated ones in [tests](tests). For example, to regenerate the screenshots one can run: ```bash $ python3 tests/run_tests.py --create-ref ``` And to simply run the tests to compare to, eliminate that argument. By default, a random port is selected, along with other arguments. One can see usage via: ```bash $ python tests/run_tests.py --help ``` Continuous integration tests are run via [GitHub Actions](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml). Running the tests locally requires Python 3, the Selenium Python bindings, [Pillow](https://pillow.readthedocs.io/), [NumPy](https://www.numpy.org/), and either Firefox & [geckodriver](https://github.com/mozilla/geckodriver) or Chrome & [ChromeDriver](https://chromedriver.chromium.org/). ## Seeking support If you wish to ask a question or report a bug, please open an issue at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). See the _Contributing_ section below for more details. ## Contributing Development takes place at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). Issues should be opened to report bugs or suggest improvements (or ask questions), and pull requests are welcome. Please make an attempt to write in grammatically-correct English on the issue tracker; using the results of machine translation is acceptable if one in not fluent in the language, and attempts to work past language barriers will be made. When reporting a bug, please try to include a minimum reproducible example (or at least some sort of example). When proposing changes, please try to match the existing code style, e.g., four space indentation and [JSHint](https://jshint.com/) validation. If your pull request adds an additional configuration parameter, please document it in `doc/json-config-parameters.md`. Pull requests should preferably be created from [feature branches](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow). ## LLM policy Output of large language models (LLMs) should not be used in issues or other written communications. Use of such output is disrespectful to the maintainer's time, and any issues that appear to be written by LLMs will be closed. The only exception to this rule is for machine translation into English. LLM-written code in pull requests is not strictly prohibited but must be declared and will be considered on a case-by-case basis; the pull request's author must assume fully responsibility for it, and any corresponding documentation must be written without the use of LLMs. ## License Pannellum is distributed under the MIT License. For more information, read the file `COPYING` or peruse the license [online](https://github.com/mpetroff/pannellum/blob/master/COPYING). In the past, parts of Pannellum were based on [three.js](https://github.com/mrdoob/three.js) r40, which is licensed under the [MIT License](https://github.com/mrdoob/three.js/blob/44a8652c37e576d51a7edd97b0f99f00784c3db7/LICENSE). The panoramic image provided with the examples is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/). ## Credits * [Matthew Petroff](http://mpetroff.net/), Original Author * [three.js](https://github.com/mrdoob/three.js) r40, Former Underlying Framework If used as part of academic research, please cite: > Petroff, Matthew A. "Pannellum: a lightweight web-based panorama viewer." _Journal of Open Source Software_ 4, no. 40 (2019): 1628. [doi:10.21105/joss.01628](https://doi.org/10.21105/joss.01628) --- ## File: Readme.md # Pannellum [](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml) [](https://doi.org/10.5281/zenodo.3334433) [](https://doi.org/10.21105/joss.01628) ## About 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 21kB gzipped, and then embedded into pages as an ``. A configuration utility is included to generate the required code for embedding. An API is included for more advanced integrations. ## Getting started ### Hosted examples A set of [examples](https://pannellum.org/documentation/examples/simple-example/) that demonstrate the viewer's various functionality is hosted on [pannellum.org](https://pannellum.org/). This is the best place to start if you want an overview of Pannellum's functionality. They also provide helpful starting points for creating custom configurations. ### Simple tutorial and configuration utility If you are just looking to display a single panorama without any advanced functionality, the steps for doing so are covered on the [simple tutorial page](https://pannellum.org/documentation/overview/tutorial/). Said page also includes a utility for easily creating the necessary Pannellum configuration. ### Local testing and self-hosting If you would like to locally test or self-host Pannellum, continue to the _How to use_ section below. ## How to use 1. Upload `build/pannellum.htm` and a full equirectangular panorama to a web server or run a development web server locally. * Due to browser security restrictions, _a web server must be used locally as well_. With Python 3, one can use `python3 -m http.server`, but any other web server should also work. 2. Use the included multi-resolution generator (`utils/multires/generate.py`), the configuration tool (`utils/config/configuration.htm`), or create a configuration from scratch or based on an [example](https://pannellum.org/documentation/examples/simple-example/). 3. Insert the generated `` code into a page, or create a more advanced configuration with [JSON](https://pannellum.org/documentation/reference) or the [API](https://pannellum.org/documentation/api/). Configuration parameters are documented in the `doc/json-config-parameters.md` file, which is also available at [pannellum.org/documentation/reference/](https://pannellum.org/documentation/reference). API methods are documented inline with [JSDoc](https://jsdoc.app/) comments, and generated documentation is available at [pannellum.org/documentation/api/](https://pannellum.org/documentation/api/). For the standalone viewer, configuration parameters are preferably specified using a location hash instead of a location search query, e.g., `pannellum.htm#panorama=...` instead of `pannellum.htm?panorama=...`, since this does not unnecessarily send the query parameters to the server. ### Using a minified copy For final deployment, it is recommended that one use a minified copy of Pannellum instead of using the source files in `src` directly. The easiest method is to download the most recent [release](https://github.com/mpetroff/pannellum/releases) and use the pre-built copy of either `pannellum.htm` or `pannellum.js` & `pannellum.css`. If you wish to make changes to Pannellum or use the latest development copy of the code, follow the instructions in the _Building_ section below to create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`. ### Using `generate.py` to create multires panoramas To be able to create multiresolution panoramas, you need to have the `nona` program installed, which is available as part of [Hugin](http://hugin.sourceforge.net/), as well as Python 3 with the [Pillow](https://pillow.readthedocs.org/) and [NumPy](https://numpy.org/) packages. The [pyshtools](https://shtools.github.io/SHTOOLS/) Python package is also recommended. Then, run ``` python3 generate.py pano_image.jpg ``` in the `utils/multires` directory. This will generate all the image tiles and the `config.json` file in the `./output` folder by default. For this to work, `nona` needs to be on the system path; otherwise, the location of `nona` can be specified using the `-n` flag. On a Unix-like platform, with `nona` already on the system path use: ```bash $ cd utils/multires $ python3 generate.py pano_image.jpg ``` where `pano_image.jpg` is the filename of your equirectangular panorama. If `nona` is not on the system path, use: ```bash $ cd utils/multires $ python3 generate.py -n /path/to/nona pano_image.jpg ``` For a complete list of options, run: ```bash $ python3 generate.py --help ``` To view the generated configuration, run: ```bash $ cd ../.. $ python3 -m http.server ``` This goes back to the root directory of the repository and starts a local development web server. Then open http://localhost:8000/src/standalone/pannellum.htm#config=../../utils/multires/output/config.json in your web browser of choice. ## Bundled examples Examples using both the minified version and the version in the `src` directory are included in the `examples` directory. These can be viewed by starting a local web server in the root of the repository, e.g., by running: ```bash $ python3 -m http.server ``` in the directory containing this readme file, and then navigating to the hosted HTML files using a web browser; note that the examples use files from the `src` directory, so **the web server must be started from the repository root, not the `examples` directory**. For the `example-minified.htm` example to work, a minified copy of Pannellum must first be built; see the _Building_ section below for details. Additional examples are available at [pannellum.org](https://pannellum.org/documentation/examples/simple-example/). ## Browser Compatibility Since Pannellum is built with web standards, it requires a modern browser to function. #### Full support (with appropriate graphics drivers): * Firefox 40+ * Chrome 41+ * Safari 9+ * Edge 12+ The support list is based on feature support. As only recent browsers are tested, there may be regressions in older browsers. #### Not officially supported: Mobile / app / web frameworks are not officially supported. They may work, but they're not tested and are not the targeted platform. ## Translations All user-facing strings can be changed using the `strings` configuration parameter. There exists a [third-party respository of user-contributed translations](https://github.com/DanielBiegler/pannellum-translation) that can be used with this configuration option. ## Building The `utils` folder contains the required build tools, with the exception of Python 3.2+ and Java installations. To build a minified version of Pannellum, run either `build.sh` or `build.bat` depending on your platform. On a Unix-like platform: ```bash $ cd utils/build $ ./build.sh ``` If successful, this should create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`, relative to the root directory of the repository. ## Tests A minimal [Selenium](https://www.seleniumhq.org/)-based test suite is located in the `tests` directory. The tests can be executed by running: ```bash python3 run_tests.py ``` A Selenium-driven web browser (with a Chrome driver, by default) is created, and screenshots are generated and compared against previously generated ones in [tests](tests). For example, to regenerate the screenshots one can run: ```bash $ python3 tests/run_tests.py --create-ref ``` And to simply run the tests to compare to, eliminate that argument. By default, a random port is selected, along with other arguments. One can see usage via: ```bash $ python tests/run_tests.py --help ``` Continuous integration tests are run via [GitHub Actions](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml). Running the tests locally requires Python 3, the Selenium Python bindings, [Pillow](https://pillow.readthedocs.io/), [NumPy](https://www.numpy.org/), and either Firefox & [geckodriver](https://github.com/mozilla/geckodriver) or Chrome & [ChromeDriver](https://chromedriver.chromium.org/). ## Seeking support If you wish to ask a question or report a bug, please open an issue at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). See the _Contributing_ section below for more details. ## Contributing Development takes place at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). Issues should be opened to report bugs or suggest improvements (or ask questions), and pull requests are welcome. Please make an attempt to write in grammatically-correct English on the issue tracker; using the results of machine translation is acceptable if one in not fluent in the language, and attempts to work past language barriers will be made. When reporting a bug, please try to include a minimum reproducible example (or at least some sort of example). When proposing changes, please try to match the existing code style, e.g., four space indentation and [JSHint](https://jshint.com/) validation. If your pull request adds an additional configuration parameter, please document it in `doc/json-config-parameters.md`. Pull requests should preferably be created from [feature branches](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow). ## LLM policy Output of large language models (LLMs) should not be used in issues or other written communications. Use of such output is disrespectful to the maintainer's time, and any issues that appear to be written by LLMs will be closed. The only exception to this rule is for machine translation into English. LLM-written code in pull requests is not strictly prohibited but must be declared and will be considered on a case-by-case basis; the pull request's author must assume fully responsibility for it, and any corresponding documentation must be written without the use of LLMs. ## License Pannellum is distributed under the MIT License. For more information, read the file `COPYING` or peruse the license [online](https://github.com/mpetroff/pannellum/blob/master/COPYING). In the past, parts of Pannellum were based on [three.js](https://github.com/mrdoob/three.js) r40, which is licensed under the [MIT License](https://github.com/mrdoob/three.js/blob/44a8652c37e576d51a7edd97b0f99f00784c3db7/LICENSE). The panoramic image provided with the examples is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/). ## Credits * [Matthew Petroff](http://mpetroff.net/), Original Author * [three.js](https://github.com/mrdoob/three.js) r40, Former Underlying Framework If used as part of academic research, please cite: > Petroff, Matthew A. "Pannellum: a lightweight web-based panorama viewer." _Journal of Open Source Software_ 4, no. 40 (2019): 1628. [doi:10.21105/joss.01628](https://doi.org/10.21105/joss.01628) --- ## File: readme.md # Pannellum [](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml) [](https://doi.org/10.5281/zenodo.3334433) [](https://doi.org/10.21105/joss.01628) ## About 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 21kB gzipped, and then embedded into pages as an ``. A configuration utility is included to generate the required code for embedding. An API is included for more advanced integrations. ## Getting started ### Hosted examples A set of [examples](https://pannellum.org/documentation/examples/simple-example/) that demonstrate the viewer's various functionality is hosted on [pannellum.org](https://pannellum.org/). This is the best place to start if you want an overview of Pannellum's functionality. They also provide helpful starting points for creating custom configurations. ### Simple tutorial and configuration utility If you are just looking to display a single panorama without any advanced functionality, the steps for doing so are covered on the [simple tutorial page](https://pannellum.org/documentation/overview/tutorial/). Said page also includes a utility for easily creating the necessary Pannellum configuration. ### Local testing and self-hosting If you would like to locally test or self-host Pannellum, continue to the _How to use_ section below. ## How to use 1. Upload `build/pannellum.htm` and a full equirectangular panorama to a web server or run a development web server locally. * Due to browser security restrictions, _a web server must be used locally as well_. With Python 3, one can use `python3 -m http.server`, but any other web server should also work. 2. Use the included multi-resolution generator (`utils/multires/generate.py`), the configuration tool (`utils/config/configuration.htm`), or create a configuration from scratch or based on an [example](https://pannellum.org/documentation/examples/simple-example/). 3. Insert the generated `` code into a page, or create a more advanced configuration with [JSON](https://pannellum.org/documentation/reference) or the [API](https://pannellum.org/documentation/api/). Configuration parameters are documented in the `doc/json-config-parameters.md` file, which is also available at [pannellum.org/documentation/reference/](https://pannellum.org/documentation/reference). API methods are documented inline with [JSDoc](https://jsdoc.app/) comments, and generated documentation is available at [pannellum.org/documentation/api/](https://pannellum.org/documentation/api/). For the standalone viewer, configuration parameters are preferably specified using a location hash instead of a location search query, e.g., `pannellum.htm#panorama=...` instead of `pannellum.htm?panorama=...`, since this does not unnecessarily send the query parameters to the server. ### Using a minified copy For final deployment, it is recommended that one use a minified copy of Pannellum instead of using the source files in `src` directly. The easiest method is to download the most recent [release](https://github.com/mpetroff/pannellum/releases) and use the pre-built copy of either `pannellum.htm` or `pannellum.js` & `pannellum.css`. If you wish to make changes to Pannellum or use the latest development copy of the code, follow the instructions in the _Building_ section below to create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`. ### Using `generate.py` to create multires panoramas To be able to create multiresolution panoramas, you need to have the `nona` program installed, which is available as part of [Hugin](http://hugin.sourceforge.net/), as well as Python 3 with the [Pillow](https://pillow.readthedocs.org/) and [NumPy](https://numpy.org/) packages. The [pyshtools](https://shtools.github.io/SHTOOLS/) Python package is also recommended. Then, run ``` python3 generate.py pano_image.jpg ``` in the `utils/multires` directory. This will generate all the image tiles and the `config.json` file in the `./output` folder by default. For this to work, `nona` needs to be on the system path; otherwise, the location of `nona` can be specified using the `-n` flag. On a Unix-like platform, with `nona` already on the system path use: ```bash $ cd utils/multires $ python3 generate.py pano_image.jpg ``` where `pano_image.jpg` is the filename of your equirectangular panorama. If `nona` is not on the system path, use: ```bash $ cd utils/multires $ python3 generate.py -n /path/to/nona pano_image.jpg ``` For a complete list of options, run: ```bash $ python3 generate.py --help ``` To view the generated configuration, run: ```bash $ cd ../.. $ python3 -m http.server ``` This goes back to the root directory of the repository and starts a local development web server. Then open http://localhost:8000/src/standalone/pannellum.htm#config=../../utils/multires/output/config.json in your web browser of choice. ## Bundled examples Examples using both the minified version and the version in the `src` directory are included in the `examples` directory. These can be viewed by starting a local web server in the root of the repository, e.g., by running: ```bash $ python3 -m http.server ``` in the directory containing this readme file, and then navigating to the hosted HTML files using a web browser; note that the examples use files from the `src` directory, so **the web server must be started from the repository root, not the `examples` directory**. For the `example-minified.htm` example to work, a minified copy of Pannellum must first be built; see the _Building_ section below for details. Additional examples are available at [pannellum.org](https://pannellum.org/documentation/examples/simple-example/). ## Browser Compatibility Since Pannellum is built with web standards, it requires a modern browser to function. #### Full support (with appropriate graphics drivers): * Firefox 40+ * Chrome 41+ * Safari 9+ * Edge 12+ The support list is based on feature support. As only recent browsers are tested, there may be regressions in older browsers. #### Not officially supported: Mobile / app / web frameworks are not officially supported. They may work, but they're not tested and are not the targeted platform. ## Translations All user-facing strings can be changed using the `strings` configuration parameter. There exists a [third-party respository of user-contributed translations](https://github.com/DanielBiegler/pannellum-translation) that can be used with this configuration option. ## Building The `utils` folder contains the required build tools, with the exception of Python 3.2+ and Java installations. To build a minified version of Pannellum, run either `build.sh` or `build.bat` depending on your platform. On a Unix-like platform: ```bash $ cd utils/build $ ./build.sh ``` If successful, this should create `build/pannellum.htm`, `build/pannellum.js`, and `build/pannellum.css`, relative to the root directory of the repository. ## Tests A minimal [Selenium](https://www.seleniumhq.org/)-based test suite is located in the `tests` directory. The tests can be executed by running: ```bash python3 run_tests.py ``` A Selenium-driven web browser (with a Chrome driver, by default) is created, and screenshots are generated and compared against previously generated ones in [tests](tests). For example, to regenerate the screenshots one can run: ```bash $ python3 tests/run_tests.py --create-ref ``` And to simply run the tests to compare to, eliminate that argument. By default, a random port is selected, along with other arguments. One can see usage via: ```bash $ python tests/run_tests.py --help ``` Continuous integration tests are run via [GitHub Actions](https://github.com/mpetroff/pannellum/actions/workflows/ci.yaml). Running the tests locally requires Python 3, the Selenium Python bindings, [Pillow](https://pillow.readthedocs.io/), [NumPy](https://www.numpy.org/), and either Firefox & [geckodriver](https://github.com/mozilla/geckodriver) or Chrome & [ChromeDriver](https://chromedriver.chromium.org/). ## Seeking support If you wish to ask a question or report a bug, please open an issue at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). See the _Contributing_ section below for more details. ## Contributing Development takes place at [github.com/mpetroff/pannellum](https://github.com/mpetroff/pannellum). Issues should be opened to report bugs or suggest improvements (or ask questions), and pull requests are welcome. Please make an attempt to write in grammatically-correct English on the issue tracker; using the results of machine translation is acceptable if one in not fluent in the language, and attempts to work past language barriers will be made. When reporting a bug, please try to include a minimum reproducible example (or at least some sort of example). When proposing changes, please try to match the existing code style, e.g., four space indentation and [JSHint](https://jshint.com/) validation. If your pull request adds an additional configuration parameter, please document it in `doc/json-config-parameters.md`. Pull requests should preferably be created from [feature branches](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow). ## LLM policy Output of large language models (LLMs) should not be used in issues or other written communications. Use of such output is disrespectful to the maintainer's time, and any issues that appear to be written by LLMs will be closed. The only exception to this rule is for machine translation into English. LLM-written code in pull requests is not strictly prohibited but must be declared and will be considered on a case-by-case basis; the pull request's author must assume fully responsibility for it, and any corresponding documentation must be written without the use of LLMs. ## License Pannellum is distributed under the MIT License. For more information, read the file `COPYING` or peruse the license [online](https://github.com/mpetroff/pannellum/blob/master/COPYING). In the past, parts of Pannellum were based on [three.js](https://github.com/mrdoob/three.js) r40, which is licensed under the [MIT License](https://github.com/mrdoob/three.js/blob/44a8652c37e576d51a7edd97b0f99f00784c3db7/LICENSE). The panoramic image provided with the examples is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/). ## Credits * [Matthew Petroff](http://mpetroff.net/), Original Author * [three.js](https://github.com/mrdoob/three.js) r40, Former Underlying Framework If used as part of academic research, please cite: > Petroff, Matthew A. "Pannellum: a lightweight web-based panorama viewer." _Journal of Open Source Software_ 4, no. 40 (2019): 1628. [doi:10.21105/joss.01628](https://doi.org/10.21105/joss.01628) --- ## File: doc/events.md # API Events ## `load` Fired when a panorama finishes loading. ## `scenechange` Fired when a scene change is initiated. A `load` event will be fired when the new scene finishes loading. Passes scene ID string to handler. ## `fullscreenchange` Fired when browser fullscreen status changed. Passes status boolean to handler. ## `zoomchange` Fired when scene hfov update. Passes new HFOV value to handler. ## `scenechangefadedone` If a scene transition fade interval is specified, this event is fired when the fading is completed after changing scenes. ## `animatefinished` Fired when any movements / animations finish, i.e. when the renderer stops rendering new frames. Passes final pitch, yaw, and HFOV values to handler. ## `error` Fired when an error occured. The error message string is passed to the event listener. ## `errorcleared` Fired when an error is cleared. ## `mousedown` Fired when the mouse button is pressed. Passes `MouseEvent` to handler. ## `mouseup` Fired when the mouse button is released. Passes `MouseEvent` to handler. ## `touchstart` Fired when a touch starts. Passes `TouchEvent` to handler. ## `touchend` Fired when a touch ends. Passes `TouchEvent` to handler. ## `messageshown` Fired when a message, e.g., for needing `ctrl` + scroll to zoom, is shown. ## `messagecleared` Fired when a previously shown message is cleared. --- ## File: doc/json-config-parameters.md # JSON Configuration File Options ## General options ### `type` (string) This specifies the panorama type. Can be `equirectangular`, `cubemap`, or `multires`. Defaults to `equirectangular`. ### `title` (string) If set, the value is displayed as the panorama's title. If no title is desired, don't set this parameter. ### `author` (string) If set, the value is displayed as the panorama's author. If no author is desired, don't set this parameter. ### `authorURL` (string) If set, the displayed author text is hyperlinked to this URL. If no author URL is desired, don't set this parameter. The `author` parameter must also be set for this parameter to have an effect. ### `strings` (dictionary) Allows user-facing strings to be changed / translated. See `defaultConfig.strings` definition in `pannellum.js` for more details. ### `basePath` (string) This specifies a base path to load the images from. ### `autoLoad` (boolean) When set to `true`, the panorama will automatically load. When `false`, the user needs to click on the load button to load the panorama. Defaults to `false`. ### `autoRotate` (number) Setting this parameter causes the panorama to automatically rotate when loaded. The value specifies the rotation speed in degrees per second. Positive is counter-clockwise, and negative is clockwise. ### `autoRotateInactivityDelay` (number) Sets the delay, in milliseconds, to start automatically rotating the panorama after user activity ceases. This parameter only has an effect if the `autoRotate` parameter is set. Before starting rotation, the viewer is panned to the initial pitch. ### `autoRotateStopDelay` (number) Sets the delay, in milliseconds, to stop automatically rotating the panorama after it is loaded. This parameter only has an effect if the `autoRotate` parameter is set. ### `orientationOnByDefault` (boolean) If set to `true`, device orientation control will be used when the panorama is loaded, if the device supports it. If false, device orientation control needs to be activated by pressing a button. Defaults to `false`. Note that a secure HTTPS connection is required for device orientation access in most browsers. Additionally, this feature does not work in combination with `autoLoad: true` in most browsers, since a user interaction is required to prompt for permission. ### `showZoomCtrl` (boolean) If set to `false`, the zoom controls will not be displayed. Defaults to `true`. ### `keyboardZoom` (boolean) If set to `false`, zooming with keyboard will be disabled. Defaults to `true`. ### `mouseZoom` (boolean or string) If set to `false`, zooming with mouse wheel will be disabled. Defaults to `true`. Can also be set to `fullscreenonly`, in which case it is only enabled when the viewer is fullscreen. Can also be set to `ctrl`, in which case the `ctrl` key must be held down to zoom with the mouse wheel (except while the viewer is fullscreen); when the `ctrl` key is required for mouse wheel zooming, the use of `ctrl` / `shift` for zoom control is disabled. ### `doubleClickZoom` (boolean) If set to `false`, the zoom to click location on double click function will be disabled. Defaults to `true`. ### `draggable` (boolean) If set to `false`, mouse and touch dragging is disabled. Defaults to `true`. ### `dragConfirm` (boolean or string) If set to `false`, one finger can be used to pan viewer. Defaults to `false`. Can also be set to `pitch`, `yaw`, or `both`. If set to `pitch` or `both`, two fingers need to be used to pan vertically (except while the viewer is fullscreen). If set to `yaw` or `both`, two fingers need to be used to pan horizontally (except while the viewer is fullscreen). ### `friction` (number) Controls the "friction" that slows down the viewer motion after it is dragged and released. Higher values mean the motion stops faster. Should be set (0.0, 1.0]; defaults to 0.15. ### `disableKeyboardCtrl` (boolean) If set to `true`, keyboard controls are disabled. Defaults to `false`. ### `showFullscreenCtrl` (boolean) If set to `false`, the fullscreen control will not be displayed. Defaults to `true`. The fullscreen button will only be displayed if the browser supports the fullscreen API. ### `showControls` (boolean) If set to `false`, no controls are displayed. Defaults to `true`. ### `touchPanSpeedCoeffFactor` (number) Adjusts panning speed from touch inputs. Defaults to `1`. ### `yaw` (number) Sets the panorama's starting yaw position in degrees. Defaults to `0`. ### `pitch` (number) Sets the panorama's starting pitch position in degrees. Defaults to `0`. ### `hfov` (number) Sets the panorama's starting horizontal field of view in degrees. Defaults to `100`. ### `minYaw` and `maxYaw` (number) Sets the minimum / maximum yaw the viewer edge can be at, in degrees. Defaults to `-180` / `180`, i.e., no limit, which are also the minimum and maximum values for these parameters. A further restriction is `minYaw` must be less than `maxYaw`, and with these parameters set, the viewer cannot pass the +/-180 degree point. ### `minPitch` and `maxPitch` (number) Sets the minimum / maximum pitch the viewer edge can be at, in degrees. Defaults to `undefined`, so the viewer center can reach `-90` / `90`. ### `minHfov` and `maxHfov` (number) Sets the minimum / maximum horizontal field of view, in degrees, that the viewer can be set to. Defaults to `50` / `120`. Unless the `multiResMinHfov` parameter is set to `true`, the `minHfov` parameter is ignored for `multires` panoramas. ### `multiResMinHfov` (boolean) When set to `false`, the `minHfov` parameter is ignored for `multires` panoramas; an automatically calculated minimum horizontal field of view is used instead. Defaults to `false`. ### `compass` (boolean) If `true`, a compass is displayed. Normally defaults to `false`; defaults to `true` if heading information is present in Photo Sphere XMP metadata. ### `northOffset` (number) Set the offset, in degrees, of the center of the panorama from North. As this affects the compass, it only has an effect if `compass` is set to `true`. ### `preview` (string) Specifies a URL for a preview image to display before the panorama is loaded. ### `previewTitle` (string) Specifies the title to be displayed while the load button is displayed. ### `previewAuthor` (string) Specifies the author to be displayed while the load button is displayed. ### `horizonPitch` and `horizonRoll` (number) Specifies pitch / roll of image horizon, in degrees (for correcting non-leveled panoramas). ### `animationTimingFunction` (function) [API only] This specifies a timing function to be used for animating movements such as when the `lookAt` method is called. The default timing function is `easeInOutQuad`. If a custom function is specified, it should take a number [0, 1] as its only argument and return a number [0, 1]. ### `escapeHTML` (boolean) When true, HTML is escaped from configuration strings to help mitigate possible DOM XSS attacks. This is always `true` when using the standalone viewer since the configuration is provided via the URL; it defaults to `false` but can be set to `true` when using the API. ### `targetBlank` (boolean) When `true`, `target="_blank"` is set on most hyperlinks to open them in new tabs. This is always `true` when using the standalone viewer since said viewer is often used in an ``, where it doesn't make sense to open the link in the same place. Defaults to `false`. ### `crossOrigin` (string) This specifies the type of CORS request used and can be set to either `anonymous` or `use-credentials`. Defaults to `anonymous`. ### `hotSpots` (object) This specifies a dictionary of hot spots that can be links to other scenes, information, or external links. Each array element has the following properties. #### `pitch` (number) Specifies the pitch portion of the hot spot's location, in degrees. #### `yaw` (number) Specifies the yaw portion of the hot spot's location, in degrees. #### `type` (string) Specifies the type of the hot spot. Can be `scene` for scene links or `info` for information hot spots. A tour configuration file is required for `scene` hot spots. #### `text` (string) This specifies the text that is displayed when the user hovers over the hot spot. #### `URL` (string) If specified for an `info` hot spot, the hot spot links to the specified URL. Not applicable for `scene` hot spots. #### `attributes` (dict) Specifies URL's link attributes. If not set, the `target` attribute is set to `_blank`, to open link in new tab to avoid opening in viewer frame / page. #### `sceneId` (string) Specifies the ID of the scene to link to for `scene` hot spots. Not applicable for `info` hot spots. #### `targetPitch` (number) Specifies the pitch of the target scene, in degrees. Can also be set to `same`, which uses the current pitch of the current scene as the initial pitch of the target scene. #### `targetYaw` (number) Specifies the yaw of the target scene, in degrees. Can also be set to `same` or `sameAzimuth`. These settings use the current yaw of the current scene as the initial yaw of the target scene; `same` uses the current yaw directly, while `sameAzimuth` takes into account the `northOffset` values of both scenes to maintain the same direction with regard to north. #### `targetHfov` (number) Specifies the HFOV of the target scene, in degrees. Can also be set to `same`, which uses the current HFOV of the current scene as the initial HFOV of the target scene. #### `id` (string) Specifies hot spot ID, for use with API's `removeHotSpot` function. #### `cssClass` (string) If specified, string is used as the CSS class for the hot spot instead of the default CSS classes. #### `createTooltipFunc` (function) and `createTooltipArgs` (object) If `createTooltipFunc` is specified, this function is used to create the hot spot tooltip DOM instead of the default function. The contents of `createTooltipArgs` are passed to the function as arguments. #### `clickHandlerFunc` (function) and `clickHandlerArgs` (object) If `clickHandlerFunc` is specified, this function is added as an event handler for the hot spot's `click`, `pointerup`, and `touchend` events. The event object and the contents of `clickHandlerArgs` are passed to the function as arguments. #### `draggable` If specified, the hotspot can moved using the mouse or by touch. #### `dragHandlerFunc` (function) and `dragHandlerArgs` (object) If `dragHandlerFunc` is specified, this function is added as an event handler when dragging of the hotspot starts and ends. The event object and the contents of `dragHandlerArgs` are passed to the function as arguments. Possible types of the event object are: `mousedown`, `pointerdown`, `touchend`, `pointerup`, `pointerleave`, `mouseup`, and `mouseleave`. #### `scale` (boolean or number) When `true`, the hot spot is scaled to match changes in the field of view, relative to the initial field of view. Note that this does not account for changes in local image scale that occur due to distortions within the viewport. Defaults to `false`. #### `scaleFactor` (number) Applies a fixed scaling to the default hot spot size. Can be combined with `scale`. ### `hotSpotDebug` (boolean) When `true`, the mouse pointer's pitch and yaw are logged to the console when the mouse button is clicked. Defaults to `false`. ### `sceneFadeDuration` (number) Specifies the fade duration, in milliseconds, when transitioning between scenes. Not defined by default. Only applicable for tours. Only works with WebGL renderer. ### `capturedKeyNumbers` (array) Specifies the key numbers that are captured in key events. Defaults to the standard keys that are used by the viewer. ### `backgroundColor` ([number, number, number]) Specifies an array containing RGB values [0, 1] that sets the background color for areas where no image data is available. Defaults to `[0, 0, 0]` (black). For partial `equirectangular` panoramas this applies to areas past the edges of the defined rectangle. For `multires` and `cubemap` (including fallback) panoramas this applies to areas corresponding to missing tiles or faces. If set to `null`, the background is not cleared. ### `avoidShowingBackground` (boolean) If set to `true`, prevent displaying out-of-range areas of a partial panorama by constraining the yaw and the field-of-view. Even at the corners and edges of the canvas only areas actually belonging to the image (i.e., within [`minYaw`, `maxYaw`] and [`minPitch`, `maxPitch`]) are shown, thus setting the `backgroundColor` option is not needed if this option is set. Defaults to `false`. The `minPitch` and `maxPitch` parameters must be defined if this option is enabled. ## `equirectangular` specific options ### `panorama` (string or HTMLImageElement or ImageData or ImageBitmap) If a string is passed, it sets the URL to the equirectangular panorama image. This is relative to `basePath` if it is set, else it is relative to the location of `pannellum.htm`. An absolute URL can also be used. Alternatively, an already loaded image can be passed. ### `haov` (number) Sets the panorama's horizontal angle of view, in degrees. Defaults to `360`. This is used if the equirectangular image does not cover a full 360 degrees in the horizontal. ### `vaov` (number) Sets the panorama's vertical angle of view, in degrees. Defaults to `180`. This is used if the equirectangular image does not cover a full 180 degrees in the vertical. ### `vOffset` (number) Sets the vertical offset of the center of the equirectangular image from the horizon, in degrees. Defaults to `0`. This is used if `vaov` is less than `180` and the equirectangular image is not cropped symmetrically. ### `ignoreGPanoXMP` (boolean) If set to `true`, any embedded Photo Sphere XMP data will be ignored; else, said data will override any existing settings. Defaults to `false`. ## `cubemap` specific options ### `cubeMap` This is an array of URLs for the six cube faces in the order front, right, back, left, up, down. These are relative to `basePath` if it is set, else they are relative to the location of `pannellum.htm`. Absolute URLs can also be used. Partial cubemap images may be specified by giving `null` instead of a URL. ## `multires` specific options ### `multiRes` This contains information about the multiresolution panorama in sub-keys. #### `basePath` (string) This is the base path of the URLs for the multiresolution tiles. It is relative to the regular `basePath` option if it is defined, else it is relative to the location of `pannellum.htm`. An absolute URL can also be used. #### `path` (string) This is a format string for the location of the multiresolution tiles, relative to `multiRes.basePath`, which is relative to `basePath`. Format parameters are `%l` for the zoom level, `%s` for the cube face, `%x` for the x index, and `%y` for the y index. For each tile, `.extension` is appended. #### `fallbackPath` (string) This is a format string for the location of the fallback tiles for the CSS 3D transform-based renderer if the WebGL renderer is not supported, relative to `multiRes.basePath`, which is relative to `basePath`. The only format parameter is `%s`, for the cube face. For each face, `.extension` is appended. #### `extension` (string) Specifies the tiles' file extension. Do not include the `.`. #### `tileResolution` (number) This specifies the size in pixels of each image tile. #### `maxLevel` (number) This specifies the maximum zoom level. #### `cubeResolution` (number) This specifies the size in pixels of the full resolution cube faces the image tiles were created from. #### `shtHash` (string) Specifies the spherical-harmonic-transform-based preview hash. This is rendered instead of the background color before the base set of cube faces are loaded. #### `equirectangularThumbnail` (string or HTMLImageElement or ImageData or ImageBitmap) Specifies a equirectangular preview thumbnail to be rendered instead of the background color or SHT hash before the base set of cube faces are loaded. This image can either be specified as a Base64-encoded string or as an object that can be directly uploaded to a WebGL texture, e.g., `ImageData`, `ImageBitmap`, `HTMLImageElement`, `HTMLCanvasElement` objects. If a Base64-encoded string is used, the image size should be kept small, since it needs to be loaded with the configuration parameters. #### `missingTiles` (string) This specifies tiles that are missing and should not be loaded. A compact encoding is used for these data. ## Dynamic content specific options Currently, only equirectangular dynamic content is supported. ### `dynamic` (boolean) The panorama source is considered dynamic when this is set to `true`. Defaults to `false`. This should be set to `true` for video. ### `dynamicUpdate` (boolean) For dynamic content, viewer will start automatically updating when set to `true`. Defaults to `false`. If the updates are controlled via the `setUpdate` method, as with the Video.js plugin, this should be set to `false`. ## Additional information for tour configuration files A tour configuration file contains two top level properties, `default` and `scenes`. The `default` property contains options that are used for each scene, but options specified for individual scenes override these options. The `default` property is required to have a `firstScene` property that contains the scene ID for the first scene to be displayed. The `scenes` property contains a dictionary of scenes, specified by scene IDs. The values assigned to these IDs are specific to each scene. --- ## File: doc/sht-hash.md # Spherical harmonic transform hash This document specifies a spherical harmonic transform (SHT) hash, which is intended to be a compact method of encoding a spherical panorama preview. It is based on the [BlurHash specification](https://github.com/woltapp/blurhash/blob/master/Algorithm.md) for DCT-based 2D image previews. There are three steps for creating a SHT hash: 1. Calculate real spherical harmonic transform coefficients 2. Encode with compact binary encoding 3. Encode binary data as Base-83-encoded string Spherical harmonics form an orthogonal basis for representing a function on the sphere. Combined with coefficients for each harmonic, they can be used to represent a frequency-space approximation of such a function, without boundary effects. There are multiple normalization conventions for spherical harmonics; the $4\pi$ convention is used here. Since JavaScript does not natively support complex numbers, real harmonics with separate real sine and cosine coefficients are used. Spherical harmonics, $Y_{\ell m}$, are defined for $\ell \in \mathbb{Z}^+$, with $|m| \leq \ell$. For each $Y_{\ell m}$, there is a corresponding $f_{\ell m}$ coefficient. When these coefficients are represented in a pair of matrices (one for the sine coefficient and one for the cosine coefficients) with rows indexed by $\ell$ and columns indexed by $m$, the upper triangle of the matrix is zero. Additionally, the $\ell = m = 1$ coefficient in the sine matrix is always 1 in the $4\pi$ normalization convention, which is why it is used here. Spherical harmonic coefficients are calculated separately for each color channel. Once calculated, the sine and cosine coefficients are stored in 1D arrays using row-first ordering with the upper triangle of the matrices excluded. The coefficient arrays also excludes the first row and column of the coefficient matrices since their contents are always zero, except for the $\ell = m = 1$ sine coefficient, which is always 1 (as previously mentioned). The 1D cosine coefficient array is appended to the 1D sine coefficient array, for each of the color channels. The maximum coefficient magnitude is then found across the color channels, and this value is used to normalize the coefficients in the range $[-1, 1]$. The normalized coefficients are then multiplied by 9 and converted to integers, thereby quantizing the coefficients as integer values. These signed integers in the range $[-9, 9]$ are then converted to unsigned integers in the range $[0, 18]$ by adding 9. For each coefficient, the color channel values are packed into a single number in the range $[0, 6859]$ using $R \cdot 19^2 + G \cdot 19 + B$. This number is then Base-83-encoded into a pair of characters. Color is encoded and decoded using gamma-compressed sRGB values, for simplicity. The final SHT hash string is constructed by combining the Base-83-encoded coefficients with a prefix. The first character in the prefix contains the max $\ell$ value for the coefficients, encoded as Base 83. For Pannellum, this is currently fixed at $\ell = 5$. The next character contains the maximum coefficient value, which was used in the normalization. The value is divided by 255 to normalize it to the range $[0, 1]$. This value is then multiplied by 82 and quantized as an integer, before being Base-83 encoded. For $\ell = 5$ this string is 74 characters in length. ## Base 83 A custom Base-83 encoding is used. Values are encoded individually, using one or two digits, and concatenated together. Multiple-digit values are encoded in big-endian order, with the most-significant digit first. The character set used is `0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~`. --- ## File: doc/url-config-parameters.md # URL Configuration Parameters URL parameters are used to configure Pannellum. If an `equirectangular` image is being used without some of Pannellum's more advanced features, Pannellum can be configured with just URL parameters; else, a JSON configuration file needs to be used with the `config`. ## `config` Specifies the URL of a JSON configuration file. This must be hosted on the same origin as the `pannellum.htm` file. ## Other parameters A subset of the JSON configuration file options can be used as URL parameters. These include `panorama`, `config`, `author`, `title`, `hfov`, `minHfov`, `maxHfov`, `pitch`, `minPitch`, `maxPitch`, `yaw`, `minYaw`, `maxYaw`, `haov`, `vaov`, `vOffset`, `autoLoad`, `autoRotate`, `firstScene`, `ignoreGPanoXMP`, `preview`, `fallback`, `compass`, `showFullscreenCtrl`, `showZoomCtrl`, `keyboardZoom`, `mouseZoom`, `doubleClickZoom`, `disableKeyboardCtrl`, `draggable`, `showControls`, and `dragConfirm`. --- ## File: utils/multires/readme.md # Generating multi-resolution tiles for a panorama ## Get a Panorama If you don't have your own, it's easy to use one of the examples in the repository. From this directory, run: ```bash $ cp ../../examples/examplepano.jpg . ``` ## Generate tiles To use the `generate.py` script, either its dependencies need to be installed, or [Docker](https://www.docker.com/) can be used to avoid this installation. ### Option 1: with local dependencies The `generate.py` script depends on `nona` (from [Hugin](http://hugin.sourceforge.net/)), as well as Python 3 with the [Pillow](https://pillow.readthedocs.org/) and [NumPy](https://numpy.org/) packages. The [pyshtools](https://shtools.github.io/SHTOOLS/) Python package is also recommended. On Ubuntu, these dependencies can be installed by running: ```bash $ sudo apt install python3 python3-pil python3-numpy python3-pip hugin-tools $ pip3 install --user pyshtools ``` If you have issues installing `pyshtools`, you may be on an architecture for which PyPI does not have pre-built binaries. In this case, you might need to install the dependencies described in the [pyshtools build-from-source directions](https://shtools.github.io/SHTOOLS/python-installing.html#build-from-source). Once the dependencies are installed, a tileset can generated with: ```bash $ python3 generate.py examplepano.jpg Processing input image information... Assuming --haov 360.0 Assuming --vaov 180.0 Generating cube faces... Generating tiles... Generating fallback tiles... ``` ### Option 2: with Docker A small Dockerfile is provided that allows one to easily generate a panorama tileset with the [generate.py](generate.py) script, without needing to install dependencies on one's host. First, build the Docker container: ```bash $ docker build -t generate-panorama . ``` When it's finished, you can bind the present working directory to a location in the container (`/data`) so that your image is found in the container. Notice that the output needs to be specified in a directory that is bound to the host: ```bash $ docker run -it -v $PWD:/data generate-panorama --output /data/output /data/examplepano.jpg Processing input image information... Assuming --haov 360.0 Assuming --vaov 180.0 Generating cube faces... Generating tiles... Generating fallback tiles... ``` ## Viewing output (for either method) The final output will be in your present working directory: ```bash $ ls output/ 1 2 3 config.json fallback ``` Next, change back to the root and start a server: ```bash $ cd ../.. $ python3 -m http.server ``` A generated tileset and configuration in `utils/multires/output` can then be viewed by navigating a browser to: [http://localhost:8000/src/standalone/pannellum.htm#config=../../utils/multires/output/config.json](http://localhost:8000/src/standalone/pannellum.htm#config=../../utils/multires/output/config.json) When the page is loaded, the console will output a logging stream corresponding to the HTTP requests: ```bash 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/standalone/pannellum.htm HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/css/pannellum.css HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/standalone/standalone.css HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/js/libpannellum.js HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/js/pannellum.js HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/standalone/standalone.js HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /utils/multires/output/config.json HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/css/img/background.svg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/css/img/sprites.svg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:24] "GET /src/css/img/compass.svg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:26] "GET /src/css/img/grab.svg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:27] "GET /utils/multires/output//1/r0_0.jpg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:27] "GET /utils/multires/output//1/f0_0.jpg HTTP/1.1" 200 - 127.0.0.1 - - [09/Aug/2019 09:41:27] "GET /utils/multires/output//1/u0_0.jpg HTTP/1.1" 200 - ... ``` The panorama, in multi-resolution format, should display in the browser.