make sure pannellum viewer is ready to load new photo, fixes #11054

while loading a "scene", pannellum cannot load a new panorama scene. This means we have to wait while the viewer is busy loading an existing panorama until we can load a new one.
This commit is contained in:
Martin Raifer
2025-05-21 16:35:19 +02:00
parent 5fb540b551
commit 3c9d232d41
3 changed files with 34 additions and 12 deletions
+2
View File
@@ -44,6 +44,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
#### :scissors: Operations
#### :camera: Street-Level
* Fix Mapilio photo markers from showing up on low zoom levels ([#11014], thanks [@keiffer213] and [@haipq07])
* Fix wrong 360° panorama from being displayed when navigating quickly between photos ([#11054])
#### :white_check_mark: Validation
#### :bug: Bugfixes
* Refresh numeric input fields after leaving focus with the value that is stored in the tag ([#11027])
@@ -58,6 +59,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
[#10970]: https://github.com/openstreetmap/iD/pull/10970
[#11014]: https://github.com/openstreetmap/iD/pull/11014
[#11027]: https://github.com/openstreetmap/iD/pull/11027
[#11054]: https://github.com/openstreetmap/iD/issues/1104
[@keiffer213]: https://github.com/keiffer213
[@haipq07]: https://github.com/haipq07
+28 -9
View File
@@ -9,6 +9,7 @@ const dispatch = d3_dispatch('viewerChanged');
let _currScenes = [];
let _pannellumViewer;
let _activeSceneKey;
export default {
@@ -29,7 +30,8 @@ export default {
'default': { firstScene: '' },
scenes: {},
minHfov: 20,
disableKeyboardCtrl: true
disableKeyboardCtrl: true,
sceneFadeDuration: 0
};
_pannellumViewer = window.pannellum.viewer('ideditor-pannellum-viewer', options);
@@ -96,7 +98,7 @@ export default {
* Shows the photo frame if hidden
* @param {*} context the HTML wrap of the frame
*/
showPhotoFrame: function (context) {
showPhotoFrame: function(context) {
const isHidden = context.selectAll('.photo-frame.pannellum-frame.hide').size();
if (isHidden) {
@@ -116,22 +118,22 @@ export default {
* Hides the photo frame if shown
* @param {*} context the HTML wrap of the frame
*/
hidePhotoFrame: function (viewerContext) {
hidePhotoFrame: function(viewerContext) {
viewerContext
.select('photo-frame.pannellum-frame')
.classed('hide', false);
return this;
},
},
/**
* Renders an image inside the frame
* @param {*} data the image data, it should contain an image_path attribute, a link to the actual image.
* @param {boolean} keepOrientation if true, HFOV, pitch and yaw will be kept between images
*/
selectPhoto: function (data, keepOrientation) {
const {key} = data;
if ( !(key in _currScenes) ) {
selectPhoto: function(data, keepOrientation) {
const key = _activeSceneKey = data.image_path;
if (!_currScenes.includes(key)) {
let newSceneOptions = {
showFullscreenCtrl: false,
autoLoad: false,
@@ -156,8 +158,25 @@ export default {
pitch = this.getPitch();
hfov = this.getHfov();
}
_pannellumViewer.loadScene(key, pitch, yaw, hfov);
dispatch.call('viewerChanged');
if (_pannellumViewer.isLoaded() !== false) {
_pannellumViewer.loadScene(key, pitch, yaw, hfov);
dispatch.call('viewerChanged');
} else {
// pannellum is currently loading another scene: wait for it to finish
// loading the previous panorama first
const retry = setInterval(() => {
if (_pannellumViewer.isLoaded() === false) {
// still not done: wait a bit longer
return;
}
if (_activeSceneKey === key) {
// only load scene if no other photo has been selected in the meantime
_pannellumViewer.loadScene(key, pitch, yaw, hfov);
dispatch.call('viewerChanged');
}
clearInterval(retry);
}, 100);
}
if (_currScenes.length > 3) {
const old_key = _currScenes.shift();
+4 -3
View File
@@ -483,7 +483,7 @@ export default {
_isHD = !_isHD;
_definition = _isHD ? highDefinition : standardDefinition;
that.selectImage(context, d.id)
.showViewer(context);
.showViewer(context);
});
label
@@ -518,7 +518,7 @@ export default {
.attr('href', viewerLink)
.text('panoramax.xyz');
this.getImageData(d.sequence_id, d.id).then(function(data){
this.getImageData(d.sequence_id, d.id).then(function(data) {
_currentScene = {
currentImage: null,
nextImage: null,
@@ -589,11 +589,12 @@ export default {
* @param {*} image_id
* @returns The fetched image data
*/
getImageData: async function(collection_id, image_id){
getImageData: async function(collection_id, image_id) {
const requestUrl = imageDataUrl.replace('{collectionId}', collection_id)
.replace('{itemId}', image_id);
const response = await fetch(requestUrl, { method: 'GET' });
if (!response.ok) {
throw new Error(response.status + ' ' + response.statusText);
}