2024-02-09 17:17:51 +01:00
|
|
|
<script lang="ts">
|
2024-09-12 21:30:21 +02:00
|
|
|
import { alwaysLoadOriginalFile } from '$lib/stores/preferences.store';
|
2024-04-21 12:14:54 -07:00
|
|
|
import {
|
2024-09-12 21:30:21 +02:00
|
|
|
EquirectangularAdapter,
|
2024-04-21 12:14:54 -07:00
|
|
|
Viewer,
|
2024-09-02 12:39:55 -07:00
|
|
|
events,
|
2024-04-21 12:14:54 -07:00
|
|
|
type AdapterConstructor,
|
2024-09-12 21:30:21 +02:00
|
|
|
type PluginConstructor,
|
2024-04-21 12:14:54 -07:00
|
|
|
} from '@photo-sphere-viewer/core';
|
2025-01-28 23:09:40 +08:00
|
|
|
import { SettingsPlugin } from '@photo-sphere-viewer/settings-plugin';
|
|
|
|
|
import { ResolutionPlugin } from '@photo-sphere-viewer/resolution-plugin';
|
2024-02-09 17:17:51 +01:00
|
|
|
import '@photo-sphere-viewer/core/index.css';
|
2025-01-28 23:09:40 +08:00
|
|
|
import '@photo-sphere-viewer/settings-plugin/index.css';
|
2024-02-09 17:17:51 +01:00
|
|
|
import { onDestroy, onMount } from 'svelte';
|
|
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
interface Props {
|
|
|
|
|
panorama: string | { source: string };
|
2025-01-28 23:09:40 +08:00
|
|
|
originalPanorama?: string | { source: string };
|
2024-11-14 08:43:25 -06:00
|
|
|
adapter?: AdapterConstructor | [AdapterConstructor, unknown];
|
|
|
|
|
plugins?: (PluginConstructor | [PluginConstructor, unknown])[];
|
|
|
|
|
navbar?: boolean;
|
|
|
|
|
}
|
2024-04-21 12:14:54 -07:00
|
|
|
|
2025-01-28 23:09:40 +08:00
|
|
|
let { panorama, originalPanorama, adapter = EquirectangularAdapter, plugins = [], navbar = false }: Props = $props();
|
2024-11-14 08:43:25 -06:00
|
|
|
|
|
|
|
|
let container: HTMLDivElement | undefined = $state();
|
2024-02-09 17:17:51 +01:00
|
|
|
let viewer: Viewer;
|
|
|
|
|
|
|
|
|
|
onMount(() => {
|
2024-11-14 08:43:25 -06:00
|
|
|
if (!container) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 17:17:51 +01:00
|
|
|
viewer = new Viewer({
|
2024-04-21 12:14:54 -07:00
|
|
|
adapter,
|
2025-01-28 23:09:40 +08:00
|
|
|
plugins: [
|
|
|
|
|
SettingsPlugin,
|
|
|
|
|
[
|
|
|
|
|
ResolutionPlugin,
|
|
|
|
|
{
|
|
|
|
|
defaultResolution: $alwaysLoadOriginalFile && originalPanorama ? 'original' : 'default',
|
|
|
|
|
resolutions: [
|
|
|
|
|
{
|
|
|
|
|
id: 'default',
|
|
|
|
|
label: 'Default',
|
|
|
|
|
panorama,
|
|
|
|
|
},
|
|
|
|
|
...(originalPanorama
|
|
|
|
|
? [
|
|
|
|
|
{
|
|
|
|
|
id: 'original',
|
|
|
|
|
label: 'Original',
|
|
|
|
|
panorama: originalPanorama,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
: []),
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
...plugins,
|
|
|
|
|
],
|
2024-02-09 17:17:51 +01:00
|
|
|
container,
|
2024-10-17 18:07:01 +00:00
|
|
|
touchmoveTwoFingers: false,
|
2024-04-21 12:14:54 -07:00
|
|
|
mousewheelCtrlKey: false,
|
|
|
|
|
navbar,
|
2024-10-17 18:07:01 +00:00
|
|
|
minFov: 10,
|
|
|
|
|
maxFov: 120,
|
|
|
|
|
fisheye: false,
|
2024-02-09 17:17:51 +01:00
|
|
|
});
|
2025-01-28 23:09:40 +08:00
|
|
|
const resolutionPlugin = viewer.getPlugin(ResolutionPlugin) as ResolutionPlugin;
|
2024-09-02 12:39:55 -07:00
|
|
|
|
2025-01-28 23:09:40 +08:00
|
|
|
if (originalPanorama && !$alwaysLoadOriginalFile) {
|
2024-09-02 12:39:55 -07:00
|
|
|
const zoomHandler = ({ zoomLevel }: events.ZoomUpdatedEvent) => {
|
|
|
|
|
// zoomLevel range: [0, 100]
|
|
|
|
|
if (Math.round(zoomLevel) >= 75) {
|
|
|
|
|
// Replace the preview with the original
|
2025-01-28 23:09:40 +08:00
|
|
|
void resolutionPlugin.setResolution('original');
|
2024-09-02 12:39:55 -07:00
|
|
|
viewer.removeEventListener(events.ZoomUpdatedEvent.type, zoomHandler);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
viewer.addEventListener(events.ZoomUpdatedEvent.type, zoomHandler);
|
|
|
|
|
}
|
2024-02-09 17:17:51 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
|
if (viewer) {
|
|
|
|
|
viewer.destroy();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-11-02 16:49:07 +01:00
|
|
|
<div class="h-full w-full mb-0" bind:this={container}></div>
|