MapComplete/src/UI/Image/ImagePreview.svelte

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

95 lines
2.8 KiB
Svelte
Raw Normal View History

<script lang="ts">
2023-12-19 22:08:00 +01:00
/**
* The image preview allows to drag and zoom in to the image
*/
import panzoom from "panzoom"
2025-06-16 14:46:12 +02:00
import type {
HotspotProperties,
PanoramaView,
ProvidedImage,
} from "../../Logic/ImageProviders/ImageProvider"
2025-06-05 12:21:17 +02:00
import ImageProvider from "../../Logic/ImageProviders/ImageProvider"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import Zoomcontrol from "../Zoomcontrol"
2025-03-30 19:38:36 +02:00
import { onDestroy } from "svelte"
import { PhotoSphereViewerWrapper } from "./photoSphereViewerWrapper"
import type { Feature, Geometry, Point } from "geojson"
2025-06-05 12:21:17 +02:00
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
2025-04-15 18:18:44 +02:00
export let nearbyFeatures:
| Feature<Geometry, HotspotProperties>[]
| Store<Feature<Geometry, HotspotProperties>[]> = []
2025-06-16 14:46:12 +02:00
export let image: Partial<ProvidedImage> & { url: string; id: string }
2023-12-19 22:08:00 +01:00
let panzoomInstance = undefined
let panzoomEl: HTMLElement
let viewerEl: HTMLElement
export let isLoaded: UIEventSource<boolean> = undefined
onDestroy(Zoomcontrol.createLock())
2025-04-26 13:48:15 +02:00
let destroyed = false
onDestroy(() => {
destroyed = true
})
async function initPhotosphere() {
const imageInfo: Feature<Point, PanoramaView> = await image.provider.getPanoramaInfo(image)
if (imageInfo === undefined) {
2025-06-05 12:21:17 +02:00
console.error("Image info is apparently undefined for", image)
return
}
const viewer = new PhotoSphereViewerWrapper(viewerEl, imageInfo)
2025-06-16 14:46:12 +02:00
viewer.imageInfo.addCallbackAndRunD((panoramaInfo) => {
2025-06-05 12:21:17 +02:00
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 {
2025-04-15 18:18:44 +02:00
nearbyFeatures.addCallbackAndRunD((feats) => {
viewer.setNearbyFeatures(feats)
2025-04-26 13:48:15 +02:00
return destroyed
})
}
isLoaded.set(true)
}
2023-12-19 22:08:00 +01:00
$: {
if (image.isSpherical) {
initPhotosphere()
} else if (panzoomEl) {
2023-12-19 22:08:00 +01:00
panzoomInstance = panzoom(panzoomEl, {
bounds: true,
boundsPadding: 0.49,
2024-01-16 04:21:46 +01:00
minZoom: 0.1,
2023-12-19 22:08:00 +01:00
maxZoom: 25,
2025-04-15 18:18:44 +02:00
initialZoom: 1.0,
2023-12-19 22:08:00 +01:00
})
} else {
panzoomInstance?.dispose()
}
2023-12-19 22:08:00 +01:00
}
</script>
<head>
2025-04-15 18:18:44 +02:00
<link rel="stylesheet" href="./css/pannellum.css" />
</head>
{#if image.isSpherical}
2025-04-15 18:18:44 +02:00
<div bind:this={viewerEl} class="h-full w-full" />
{:else}
<img
bind:this={panzoomEl}
class="panzoom-image h-fit max-w-fit"
on:load={() => {
2025-04-15 18:18:44 +02:00
isLoaded?.setData(true)
}}
src={image.url_hd ?? image.url}
2025-06-05 12:21:17 +02:00
alt=""
/>
{/if}