File size: 2,815 Bytes
dce7eca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import React, { useEffect, useRef, useState } from 'react';

interface PanoramaViewerProps {
    imageUrl: string;
    className?: string;
}

declare global {
    interface Window {
        pannellum: any;
    }
}

const PanoramaViewer: React.FC<PanoramaViewerProps> = ({ imageUrl, className }) => {
    const viewerRef = useRef<HTMLDivElement>(null);
    const pannellumInstance = useRef<any>(null);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        // Check if pannellum is loaded
        const initViewer = () => {
            if (!window.pannellum) {
                console.warn("Pannellum not loaded yet, retrying...");
                setTimeout(initViewer, 500);
                return;
            }

            if (viewerRef.current && imageUrl) {
                // Destroy existing instance if it exists
                if (pannellumInstance.current) {
                    try {
                        pannellumInstance.current.destroy();
                    } catch (e) {
                        console.warn("Error destroying pannellum instance:", e);
                    }
                }

                try {
                    // Initialize Pannellum
                    pannellumInstance.current = window.pannellum.viewer(viewerRef.current, {
                        type: 'equirectangular',
                        panorama: imageUrl,
                        autoLoad: true,
                        showControls: true,
                        compass: false, // Set to false by default for cleaner look
                        mouseZoom: true,
                        hfov: 100,
                        vaov: 180,
                        haov: 360,
                        crossOrigin: "anonymous"
                    });
                    setError(null);
                } catch (err: any) {
                    console.error("Pannellum initialization error:", err);
                    setError(err.message);
                }
            }
        };

        initViewer();

        return () => {
            if (pannellumInstance.current) {
                try {
                    pannellumInstance.current.destroy();
                } catch (e) { }
            }
        };
    }, [imageUrl]);

    if (error) {
        return (
            <div className="w-full h-full flex items-center justify-center bg-slate-900 text-red-400 p-4 text-center">
                <p>Error loading viewer: {error}<br />Image might be too large or inaccessible.</p>
            </div>
        );
    }

    return (
        <div
            ref={viewerRef}
            className={`w-full h-full rounded-xl overflow-hidden shadow-2xl bg-black border border-slate-700 ${className || ''}`}
        />
    );
};

export default PanoramaViewer;