MapComplete/src/UI/Image/ImagePreview.svelte

94 lines
2.8 KiB
Svelte

<script lang="ts">
/**
* The image preview allows to drag and zoom in to the image
*/
import panzoom from "panzoom"
import type {
HotspotProperties,
PanoramaView,
ProvidedImage,
} from "../../Logic/ImageProviders/ImageProvider"
import ImageProvider from "../../Logic/ImageProviders/ImageProvider"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import Zoomcontrol from "../Zoomcontrol"
import { onDestroy } from "svelte"
import { PhotoSphereViewerWrapper } from "./photoSphereViewerWrapper"
import type { Feature, Geometry, Point } from "geojson"
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
export let nearbyFeatures:
| Feature<Geometry, HotspotProperties>[]
| Store<Feature<Geometry, HotspotProperties>[]> = []
export let image: Partial<ProvidedImage> & { url: string; id: string }
let panzoomInstance = undefined
let panzoomEl: HTMLElement
let viewerEl: HTMLElement
export let isLoaded: UIEventSource<boolean> = undefined
onDestroy(Zoomcontrol.createLock())
let destroyed = false
onDestroy(() => {
destroyed = true
})
async function initPhotosphere() {
const imageInfo: Feature<Point, PanoramaView> = await image.provider.getPanoramaInfo(image)
if (imageInfo === undefined) {
console.error("Image info is apparently undefined for", image)
return
}
const viewer = new PhotoSphereViewerWrapper(viewerEl, imageInfo)
viewer.imageInfo.addCallbackAndRunD((panoramaInfo) => {
let provider: ImageProvider
if (typeof panoramaInfo.properties.provider === "string") {
provider = AllImageProviders.byName(panoramaInfo.properties.provider)
} else {
provider = panoramaInfo.properties.provider
}
console.log(">>> Got:", panoramaInfo, "by", provider.name)
//actuallyDisplayed.set(image.properties.imageMeta)
})
if (Array.isArray(nearbyFeatures)) {
viewer.setNearbyFeatures(nearbyFeatures)
} else {
nearbyFeatures.addCallbackAndRunD((feats) => {
viewer.setNearbyFeatures(feats)
return destroyed
})
}
isLoaded.set(true)
}
$: {
if (image.isSpherical) {
initPhotosphere()
} else if (panzoomEl) {
panzoomInstance = panzoom(panzoomEl, {
bounds: true,
boundsPadding: 0.49,
minZoom: 0.1,
maxZoom: 25,
initialZoom: 1.0,
})
} else {
panzoomInstance?.dispose()
}
}
</script>
<head>
<link rel="stylesheet" href="./css/pannellum.css" />
</head>
{#if image.isSpherical}
<div bind:this={viewerEl} class="h-full w-full" />
{:else}
<img
bind:this={panzoomEl}
class="panzoom-image h-fit max-w-fit"
on:load={() => {
isLoaded?.setData(true)
}}
src={image.url_hd ?? image.url}
alt=""
/>
{/if}