Last active
March 5, 2025 22:49
-
-
Save sk-zk/31df8318aead93695472b5952fb2d988 to your computer and use it in GitHub Desktop.
Embedded Look Around
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- Set the location of the panorama viewer CSS here. --> | |
<link rel="stylesheet" type="text/css" href="https://lookmap.eu.pythonanywhere.com/static/dist/viewer.css" /> | |
<style> | |
body { | |
margin: 0; | |
padding: 0; | |
} | |
#pano { | |
position: absolute; | |
width: 100vw; | |
height: 100vh; | |
z-index: 1; | |
} | |
</style> | |
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, width=device-width" /> | |
</head> | |
<body> | |
<div id="pano"></div> | |
<script type="module"> | |
// If you're running a local server, keep it as it is. | |
// Otherwise, replace it with "https://lookmap.eu.pythonanywhere.com", or your own instance if you have one. | |
// You can also point the viewer at a custom backend (e.g. to serve downloaded panoramas locally) | |
// as long as the API is the same. | |
const apiBaseUrl = "http://localhost:5000"; | |
// Set the location of the panorama viewer script here. | |
import { createPanoViewer, InitialOrientation, Api, AdditionalMetadata } from "http://localhost:5000/static/dist/viewer.js"; | |
// 1) Load the metadata of the panorama you want to start with: | |
const api = new Api(apiBaseUrl); | |
async function getPanosAt(lat, lon) { | |
return await api.getClosestPanos(lat, lon, 5, 1, | |
[AdditionalMetadata.CameraMetadata, AdditionalMetadata.Elevation, | |
AdditionalMetadata.Orientation, AdditionalMetadata.TimeZone]); | |
} | |
const initialPano = (await getPanosAt(53.54564, 9.99950))[0]; | |
// 2) Create the viewer and load this panorama: | |
const container = document.getElementById("pano"); | |
// Options for `createPanoViewer` are as follows: | |
// apiBaseUrl (required): | |
// The API base URL of the backend. Can be relative. | |
// canMove (optional): | |
// Whether the user can move between panoramas. Defaults to true. | |
// canMoveWithKeyboard (optional): | |
// Whether keyboard navigation with arrow keys is enabled. Only active | |
// if `canMove` is also true. Defaults to false. | |
// compassEnabled (optional): | |
// Whether the compass is displayed. Defaults to true. | |
// container (required): | |
// The DOM element to insert the viewer into. | |
// defaultZoomLevel (optional): | |
// The initial zoom level of the camera, between 0 to 100, | |
// relative to the specified FOV range. Defaults to 20. | |
// initialOrientation (optional): | |
// Whether the camera should initially face north or the road. | |
// Defaults to `InitialOrientation.Road`. | |
// initialPano (required): | |
// Metadata of the initial panorama to be loaded. | |
// maxFov (optional): | |
// Maximal field of view (minimum zoom), between `minFov` and 180. | |
// Defaults to 100. | |
// minFov (optional): | |
// Minimal field of view (maximum zoom), between 1 and `maxFov`. | |
// Defaults to 10. | |
// navigationCrossfadeDisablesPanning (optional): | |
// Whether panning is disabled while movement crossfade animation | |
// is playing. Defaults to true. | |
// navigationCrossfadeDuration (optional): | |
// Duration of the crossfade animation which is played when navigating | |
// to another panorama, in milliseconds. Defaults to 150. | |
// upgradeCrossfadeDuration (optional): | |
// Duration of the crossfade animation which is played when a panorama | |
// face is upgraded to a higher resolution, in milliseconds. Defaults to 150. | |
const viewer = await createPanoViewer({ | |
container: container, | |
initialPano: initialPano, | |
initialOrientation: InitialOrientation.Road, | |
apiBaseUrl: apiBaseUrl, | |
}); | |
// And that's it; the rest will be handled by the viewer. | |
// The `moved` event is triggered when the user moves to a different panorama: | |
viewer.plugins.movement.addEventListener("moved", (e) => { | |
console.log("moved", e.detail); | |
}); | |
document.addEventListener('keydown', async (e) => { | |
// To load a new location, call the `navigateTo` function. | |
// The first parameter is a panorama object, the second determines if the view should be reset. | |
if (e.key === "r") { | |
// Return to the start if [R] is pressed | |
await viewer.navigateTo(initialPano, true); | |
} | |
else if (e.key === " ") { | |
// Go to another location if [Space] is pressed | |
const someOtherPano = (await getPanosAt(43.30995, -0.76676))[0]; | |
await viewer.navigateTo(someOtherPano, true); | |
} | |
// Alternatively, it is possible to move in a specific direction | |
// rather than to a specific panorama by calling `moveInDirection`. | |
else if (e.key === "n") { | |
// If [N] is pressed, move north (0 radians) if there is a panorama | |
// approx. in that direction and within 10 and 30 meters of the current location | |
viewer.moveInDirection(0, { | |
minDistance: 10, | |
maxDistance: 30, | |
}); | |
} | |
}); | |
// If you'd like to move the compass to a different position, just change its style: | |
// const compass = document.getElementsByClassName("psv-compass")[0]; | |
// compass.style.top = "calc(100vh - 200px)"; | |
// To unload the viewer, call `destroy`: | |
// viewer.destroy(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment