1

I am trying to implement Photo Sphere Viewer on my React Component, i already did it with Google Maps API and it worked fine, but i'm using the same technique, no results. If is there any other option to implement 360 Photo Viewer on React (Already used Pannellum, didn't like it, didn't worked) i'm open to suggestions.

https://photo-sphere-viewer.js.org/

i got the html code from: https://github.com/JeremyHeleine/Photo-Sphere-Viewer/blob/master/examples/example.html

<head>
    <meta charset="utf-8" />
    <title>Photo Sphere Viewer</title>
    <meta name="viewport" content="initial-scale=1.0" />
    <script src="./three.min.js"></script>
    <script src="./photo-sphere-viewer.min.js"></script>
    <style>
        html, body {
            margin: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }

        #container {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div id="container"></div>

    <script>
        var div = document.getElementById('container');
        var PSV = new PhotoSphereViewer({
                panorama: 'http://tassedecafe.org/wp-content/uploads/2013/01/parc-saint-pierre-amiens.jpg',
                container: div,
                time_anim: 3000,
                navbar: true,
                navbar_style: {
                    backgroundColor: 'rgba(58, 67, 77, 0.7)'
                },
            });
    </script>
</body>


*import React from 'react'; 
import '../../index.css';


class ShperePanel extends React.Component{

    componentDidMount() {
        this.renderSphere();
      }

    renderSphere = () => {
        loadScript('photo-sphere-viewer.min.js');
        loadScript('three.min.js');


        window.initSphere = this.initSphere;

      }
      initSphere = () => {
        const PVS = new window.PhotoSphereViewer({ 
        container: document.getElementByid('viewer'),
        panorama: 'http://tassedecafe.org/wp-content/uploads/2013/01/parc-saint-pierre-amiens.jpg',
        time_anim: 3000,
        navbar: true,
        navbar_style: {
            backgroundColor: 'rgba(58, 67, 77, 0.7)'
        }
    })
      }
render(){
    return(
    <div id="viewer"> </div>
    );
}

}
export default ShperePanel

function loadScript(url) {
    var index = window.document.getElementsByTagName('script')[0];
    var script = window.document.createElement('script');
    script.src = url;
    script.async = true;
    script.defer = true;
    index.parentNode.insertBefore(script, index); 
  }*

i would like to get something like this.

When i try to import the scripts(three.min.js, photo-sphere-viewer.min.js), with the "import from " syntax, directly, i get an error "PhotoSphereViewer" undefined.

neubert
  • 15,947
  • 24
  • 120
  • 212
Hugo Guerrero
  • 127
  • 1
  • 3
  • 9

2 Answers2

5

React 16.8 version with useEffect hook:

import React, { useEffect } from 'react';
import PhotoSphereViewer from 'photo-sphere-viewer';

export default function Photo(props) {
  const sphereElementRef = React.createRef();
  const { src } = props;

  useEffect(() => {
    const shperePlayerInstance = PhotoSphereViewer({
      container: sphereElementRef.current,
      panorama: src,
      ... // other options
    });    

    // unmount component instructions
    return () => {
      shperePlayerInstance.destroy();
    };
  }, [src]); // will only be called when the src prop gets updated


  return (
    <div ref={sphereElementRef}/>
  );
}
Tiberiu Maxim
  • 1,474
  • 14
  • 24
3

I had similar problem and this is how I solve it:

npm install --save photo-sphere-viewer

and component look like this:

import React, { Component } from 'react'
import * as Sphere from "photo-sphere-viewer";
import "photo-sphere-viewer/dist/photo-sphere-viewer.min.css"


export default class SphereComponent extends Component {
    constructor(props) {
        super(props)
        this.divStyle = {
          width: '100%',
          height: '600px'
        };
        this.sphereDiv = element => {
            this.photoSphereViewer = element;
        };
        this.sphereDiv.appendChild = (elem) => {
            this.subDiv.appendChild(elem)
        }
    }

    componentDidMount() {
        const PVS = Sphere({
            parent: this,
            container: this.sphereDiv,
            panorama: "https://photo-sphere-viewer.js.org/assets/Bryce-Canyon-National-Park-Mark-Doliner.jpg",
            navbar: [
                'autorotate',
                'zoom',
                'fullscreen'
            ]
        })
    }

    render() {
        return <div style={this.divStyle} ref={this.sphereDiv} id="viewer"><div ref={node => this.subDiv = node} style={this.divStyle}></div></div>
    }
}

That's it.

pszafer
  • 370
  • 2
  • 15
  • 1
    How do you cleanup in componentWillUnmount? – tylermadison Sep 09 '19 at 23:24
  • You must use this.photoSphereViewer (HTML Element) as container, not this.sphereDiv (Ref callback). You can call the "destroy" method on the PVS variable to destroy the viewer on unmount. Also "parent" is not a supported option. – Mistic Sep 10 '19 at 11:18