Using Markers with photo-sphere-viewer in React/Next JS

1.4k views Asked by At

I'm struggling to find out how to use Markers in my Next JS app.

I have got a basic panorama going with this code...

import React, { useEffect } from "react";
import Head from "next/head";

import { Viewer } from "photo-sphere-viewer";

export default function Home() {
  const sphereElementRef = React.createRef();

  useEffect(() => {
    const shperePlayerInstance = new Viewer({
      container: sphereElementRef.current,
      panorama: "/images/pano2.jpg",
    });

    // unmount component instructions
    return () => {
      shperePlayerInstance.destroy();
    };
  }, []);
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />

        <link
          rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/photo-sphere-viewer@4/dist/photo-sphere-viewer.min.css"
        />
      </Head>

      <main>
        <div ref={sphereElementRef}></div>
      </main>
    </div>
  );
}

So that's all well and good but I don't know how the Markers come into it. I've tried exactly like in the markers docs with

plugins: [
[PhotoSphereViewer.MarkersPlugin, {
  markers: [ 
    {
      id: 'new-marker',
      longitude: '45deg',
      latitude: '0deg',
      image: 'assets/pin-red.png',
    },
  ],
}], 

],

But get PSVError: Un undefined value was given for plugins.

and also just using

markers: [
{
  id: 'image',
  longitude: 0.2,
  latitude: -0.13770,
  ....
},

But I just get PSVError: Unknown option markers

Any ideas would be a great help

1

There are 1 answers

2
MomasVII On BEST ANSWER

Here's my full viewer after working out how to do everything

import { Viewer } from "photo-sphere-viewer";
import { MarkersPlugin } from "photo-sphere-viewer/dist/plugins/markers";
import "photo-sphere-viewer/dist/plugins/markers.css";

import { GyroscopePlugin } from "photo-sphere-viewer/dist/plugins/gyroscope";

import { VisibleRangePlugin } from "photo-sphere-viewer/dist/plugins/visible-range";
import StereoPlugin from "photo-sphere-viewer/dist/plugins/stereo";

export default function Home() {
  const sphereElementRef = React.createRef();

  useEffect(() => {
    const shperePlayerInstance = new Viewer({
      container: sphereElementRef.current,
      panorama: "/images/pano2.jpg",
      plugins: [
        [
          VisibleRangePlugin,
          {
            longitudeRange: [null],
            latitudeRange: [-Math.PI / 2, Math.PI / 4], //Restrict range so you can't see the top of the pano
          },
        ],
        [GyroscopePlugin, StereoPlugin],
        [
          MarkersPlugin,
          {
            markers: [
              {
                id: "image",
                longitude: 0.32,
                latitude: 0.11,
                image: "/images/pin-red.png",
                width: 50,
                height: 50,
                anchor: "bottom center",
                tooltip: "A image marker.",
              },
            ],
          },
        ],
      ],
    });

    const gyroPlugin = shperePlayerInstance.getPlugin(GyroscopePlugin);
    const markersPlugin = shperePlayerInstance.getPlugin(MarkersPlugin);

    markersPlugin.on("select-marker", (e, marker) => {
      markersPlugin.updateMarker({
        id: marker.id,
      });
    });

    if (gyroPlugin && typeof gyroPlugin.isEnabled !== "function") {
      console.log("plugin issue");
    }

    if (gyroPlugin.isEnabled()) {
      gyroPlugin.stop();
    } else {
      gyroPlugin
        .start()
        .then(() => {
          const { latitude } = shperePlayerInstance.getPosition();
          const { heading } = getCompassHeadingExtra();

          shperePlayerInstance.rotate({
            longitude: heading * (Math.PI / 180),
            latitude,
          });
        })
        .catch(handleGyroEnableError);
    }

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