Panoramas Revived

August 18, 2018 0 By leigh

On my old site, I used to host panoramic pictures I had shot and stitched together using Panotools and were displayed using the PTViewer Java app. The photos c. 2001 are hardly of great quality anymore, but some of the subjects still have value, so I wanted to find a modern solution.

It turns out it was relatively straightforward to host the images on WordPress using the Toolset Types plugin that I needed to use for custom post types when converting from Drupal to WordPress. This in combination with the very nice Pannellum Javascript panorama viewer produced the results I was looking for.

I had some panoramas which were fully spherical, some which were 360 cylindrical, and some which were incomplete cylindrical. Therefore I needed to specify a number of parameters for each panorama and have those control the panorama display. Pannellum has quite a few parameters that were tweakable.

The solution was to define a custom panorama post type using Toolset Types, with custom fields giving the original resolution image link, desired height and width of the display window, if the picture was equirectangular or cylindrical, and the desired horizontal angle of view (for incomplete cylinders). I then created a custom template for the panorama post type which then specifies how those custom fields are used to generate HTML, and Javascript. The HTML I used just loads the scripts and creates a panorama div, which is set to run the Javascript code when the load panorama button is clicked.

<link rel="stylesheet" href=""/>
<script type="text/javascript" src=""></script>

[wpv-post-body view_template="None"]

<div id="panorama" 
     style="width: [types field='width'][/types]px; height: [types field='height'][/types]px;" 
     value="[types field='panorama_image' output='raw'][/types]" 
     panotype="[types field='panorama_type'][/types]" 
     haov="[types field='haov'][/types]"
     title="[wpv-post-title output="sanitize"]"></div>

I used the declaration of cyclindrical to conditionally set a number of parameters bounding the min and max pitch and yaw of the viewer. The Javascript which reads from the panorama div on each page which is specified on the Toolset Type panorama content template is:

panoramaDiv = $("#panorama")
if (panoramaDiv.attr("panotype") == "cylindrical") {
    var halfAngleOfView = Number(panoramaDiv.attr("haov")) / 2;
    // console.log(halfAngleOfView);
    viewer = pannellum.viewer('panorama', {
        "panorama": panoramaDiv.attr("value"),
        "title": panoramaDiv.attr("title"),
        "type": "equirectangular",
        "haov": panoramaDiv.attr("haov"),
        "vaov": 80,
        "hfov": 60,
        "minYaw": -halfAngleOfView,
        "maxYaw": halfAngleOfView,
        "minPitch": -40,
        "maxPitch": 40
else {
    viewer = pannellum.viewer('panorama', {
        "panorama": panoramaDiv.attr("value"),
        "title": panoramaDiv.attr("title"),
        "type": panoramaDiv.attr("panotype")

I could have specified this using IFRAMEs, but this requires a CORS declaration, which didn’t seem possible from my hosting provider.