File size: 2,969 Bytes
e429049
 
 
f42fa3f
 
e429049
 
 
 
 
 
f42fa3f
e429049
 
 
f42fa3f
e429049
 
 
 
 
f42fa3f
e429049
f42fa3f
e429049
 
 
 
 
 
 
 
 
 
 
f42fa3f
e429049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f42fa3f
e429049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f42fa3f
e429049
 
f42fa3f
e429049
 
 
 
 
 
 
 
f42fa3f
e429049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"use client"

import { useEffect, useRef, useState } from "react"
import { PluginConstructor, Viewer } from "@photo-sphere-viewer/core"
import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer"

import { useImageDimension } from "@/lib/useImageDimension"

type PhotoSpherePlugin = (PluginConstructor | [PluginConstructor, any])

export function SphericalImage({
  assetUrl,
  className,
  debug,
}: {
  assetUrl: string
  className?: string
  debug?: boolean
}) {


  const imageDimension = useImageDimension(assetUrl)

  const sceneConfig = JSON.stringify({ assetUrl, debug, imageDimension })
  const [lastSceneConfig, setLastSceneConfig] = useState<string>(sceneConfig)
  const rootContainerRef = useRef<HTMLDivElement>(null)
  const viewerContainerRef = useRef<HTMLElement>()
  const viewerRef = useRef<Viewer>()
  const [mouseMoved, setMouseMoved] = useState<boolean>(false)

  const defaultZoomLvl = 1 // 0 = 180 fov, 100 = 1 fov

  const options = {
    defaultZoomLvl,
    fisheye: false, // ..no!
    overlay:  undefined,
    overlayOpacity: debug ? 0.5 : 0,
    /*
    panoData: {
      fullWidth: 2000,
      fullHeight: 1200,
      croppedWidth: 1024,
      croppedHeight: 512,
      croppedX: 0,
      croppedY: 200,
      // poseHeading: 0, // 0 to 360
      posePitch: 0, // -90 to 90
      // poseRoll: 0, // -180 to 180
    }
    */
  }

  useEffect(() => {
    const task = async () => {
      // console.log("SphericalImage: useEffect")
      if (sceneConfig !== lastSceneConfig) {
        // console.log("SphericalImage: scene config changed!")
    
        if (!viewerRef.current) {
          // console.log("SphericalImage: no ref!")
          setLastSceneConfig(sceneConfig)
          return
        }
        const viewer = viewerRef.current

        const newOptions = {
          ...options,
        }

        await viewer.setPanorama(assetUrl, {
          ...newOptions,
          showLoader: false,
        })

        // TODO we should separate all those updates, probaby
        viewer.setOptions(newOptions)
        // viewer.setOverlay(rendered.maskUrl || undefined)

        // console.log("SphericalImage: asking to re-render")
        viewerRef.current.needsUpdate()

        setLastSceneConfig(sceneConfig)
      }
    }
    task()
  }, [sceneConfig, assetUrl, viewerRef.current, imageDimension])


  if (!assetUrl) {
    return null
  }

  return (
    <div
      ref={rootContainerRef}
      >
      <ReactPhotoSphereViewer
        src={assetUrl}
        container=""
        containerClass={className}
        
        height="100vh"
        width="100%"

        {...options}

        // note: photo sphere viewer performs an aggressive caching of our callbacks,
        // so we aggressively disable it by using a ref
        onClick={() => {
          // nothing to do here
        }}
    
        onReady={(instance) => {
          viewerContainerRef.current = instance.container
        }}

      />
    </div>
  )
}