@panoramax/web-viewer 3.2.3 → 4.0.0-develop-39167b4d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +13 -6
- package/CHANGELOG.md +53 -1
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +1 -1
- package/build/editor.html +10 -1
- package/build/index.css +12 -12
- package/build/index.css.map +1 -1
- package/build/index.html +1 -1
- package/build/index.js +2126 -14
- package/build/index.js.map +1 -1
- package/build/map.html +1 -1
- package/build/photo.html +1 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-400-normal..woff +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-400-normal..woff2 +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-ext-400-normal..woff +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-ext-400-normal..woff2 +0 -0
- package/build/viewer.html +12 -1
- package/build/widgets.html +1 -0
- package/config/jest/mocks.js +201 -0
- package/config/paths.js +2 -0
- package/config/webpack.config.js +52 -0
- package/docs/03_URL_settings.md +14 -16
- package/docs/05_Compatibility.md +59 -76
- package/docs/09_Develop.md +46 -11
- package/docs/90_Releases.md +2 -2
- package/docs/images/class_diagram.drawio +60 -45
- package/docs/images/class_diagram.jpg +0 -0
- package/docs/images/screenshot.jpg +0 -0
- package/docs/index.md +135 -0
- package/docs/reference/components/core/Basic.md +196 -0
- package/docs/reference/components/core/CoverageMap.md +210 -0
- package/docs/reference/components/core/Editor.md +224 -0
- package/docs/reference/components/core/PhotoViewer.md +307 -0
- package/docs/reference/components/core/Viewer.md +350 -0
- package/docs/reference/components/layout/BottomDrawer.md +35 -0
- package/docs/reference/components/layout/CorneredGrid.md +29 -0
- package/docs/reference/components/layout/Mini.md +45 -0
- package/docs/reference/components/layout/Tabs.md +45 -0
- package/docs/reference/components/menus/MapBackground.md +32 -0
- package/docs/reference/components/menus/MapFilters.md +15 -0
- package/docs/reference/components/menus/MapLayers.md +15 -0
- package/docs/reference/components/menus/MapLegend.md +15 -0
- package/docs/reference/components/menus/PictureLegend.md +16 -0
- package/docs/reference/components/menus/PictureMetadata.md +15 -0
- package/docs/reference/components/menus/PlayerOptions.md +15 -0
- package/docs/reference/components/menus/QualityScoreDoc.md +15 -0
- package/docs/reference/components/menus/ReportForm.md +15 -0
- package/docs/reference/components/menus/ShareMenu.md +15 -0
- package/docs/reference/components/ui/Button.md +40 -0
- package/docs/reference/components/ui/ButtonGroup.md +36 -0
- package/docs/reference/components/ui/CopyButton.md +38 -0
- package/docs/reference/components/ui/Grade.md +32 -0
- package/docs/reference/components/ui/LinkButton.md +45 -0
- package/docs/reference/components/ui/ListGroup.md +22 -0
- package/docs/reference/components/ui/Loader.md +56 -0
- package/docs/reference/components/ui/Map.md +239 -0
- package/docs/reference/components/ui/MapMore.md +256 -0
- package/docs/reference/components/ui/Photo.md +385 -0
- package/docs/reference/components/ui/Popup.md +56 -0
- package/docs/reference/components/ui/ProgressBar.md +32 -0
- package/docs/reference/components/ui/QualityScore.md +45 -0
- package/docs/reference/components/ui/SearchBar.md +63 -0
- package/docs/reference/components/ui/TogglableGroup.md +39 -0
- package/docs/reference/components/ui/widgets/GeoSearch.md +32 -0
- package/docs/reference/components/ui/widgets/Legend.md +49 -0
- package/docs/reference/components/ui/widgets/MapFiltersButton.md +33 -0
- package/docs/reference/components/ui/widgets/MapLayersButton.md +15 -0
- package/docs/reference/components/ui/widgets/OSMEditors.md +15 -0
- package/docs/reference/components/ui/widgets/PictureLegendActions.md +32 -0
- package/docs/reference/components/ui/widgets/Player.md +33 -0
- package/docs/reference/components/ui/widgets/Zoom.md +15 -0
- package/docs/reference/utils/API.md +334 -0
- package/docs/reference/utils/InitParameters.md +68 -0
- package/docs/reference/utils/URLHandler.md +107 -0
- package/docs/reference.md +79 -0
- package/docs/shortcuts.md +11 -0
- package/docs/tutorials/aerial_imagery.md +19 -0
- package/docs/tutorials/authentication.md +10 -0
- package/docs/tutorials/custom_widgets.md +59 -0
- package/docs/tutorials/map_style.md +39 -0
- package/docs/tutorials/migrate_v4.md +153 -0
- package/docs/tutorials/synced_coverage.md +43 -0
- package/mkdocs.yml +66 -5
- package/package.json +22 -17
- package/public/editor.html +21 -29
- package/public/index.html +17 -12
- package/public/map.html +19 -18
- package/public/photo.html +55 -0
- package/public/viewer.html +22 -26
- package/public/widgets.html +306 -0
- package/scripts/doc.js +79 -0
- package/src/components/core/Basic.css +48 -0
- package/src/components/core/Basic.js +349 -0
- package/src/components/core/CoverageMap.css +9 -0
- package/src/components/core/CoverageMap.js +139 -0
- package/src/components/core/Editor.css +23 -0
- package/src/components/core/Editor.js +390 -0
- package/src/components/core/PhotoViewer.css +48 -0
- package/src/components/core/PhotoViewer.js +499 -0
- package/src/components/core/Viewer.css +98 -0
- package/src/components/core/Viewer.js +564 -0
- package/src/components/core/index.js +12 -0
- package/src/components/index.js +13 -0
- package/src/components/layout/BottomDrawer.js +257 -0
- package/src/components/layout/CorneredGrid.js +112 -0
- package/src/components/layout/Mini.js +117 -0
- package/src/components/layout/Tabs.js +133 -0
- package/src/components/layout/index.js +9 -0
- package/src/components/menus/MapBackground.js +106 -0
- package/src/components/menus/MapFilters.js +400 -0
- package/src/components/menus/MapLayers.js +143 -0
- package/src/components/menus/MapLegend.js +34 -0
- package/src/components/menus/PictureLegend.js +257 -0
- package/src/components/menus/PictureMetadata.js +317 -0
- package/src/components/menus/PlayerOptions.js +95 -0
- package/src/components/menus/QualityScoreDoc.js +36 -0
- package/src/components/menus/ReportForm.js +133 -0
- package/src/components/menus/Share.js +100 -0
- package/src/components/menus/index.js +15 -0
- package/src/components/styles.js +383 -0
- package/src/components/ui/Button.js +77 -0
- package/src/components/ui/ButtonGroup.css +57 -0
- package/src/components/ui/ButtonGroup.js +68 -0
- package/src/components/ui/CopyButton.js +106 -0
- package/src/components/ui/Grade.js +54 -0
- package/src/components/ui/LinkButton.js +67 -0
- package/src/components/ui/ListGroup.js +66 -0
- package/src/components/ui/Loader.js +203 -0
- package/src/components/{Map.css → ui/Map.css} +5 -17
- package/src/components/{Map.js → ui/Map.js} +148 -156
- package/src/components/ui/MapMore.js +324 -0
- package/src/components/{Photo.css → ui/Photo.css} +6 -6
- package/src/components/{Photo.js → ui/Photo.js} +313 -101
- package/src/components/ui/Popup.js +145 -0
- package/src/components/ui/ProgressBar.js +104 -0
- package/src/components/ui/QualityScore.js +147 -0
- package/src/components/ui/SearchBar.js +367 -0
- package/src/components/ui/TogglableGroup.js +157 -0
- package/src/components/ui/index.js +22 -0
- package/src/components/ui/widgets/GeoSearch.css +21 -0
- package/src/components/ui/widgets/GeoSearch.js +139 -0
- package/src/components/ui/widgets/Legend.js +113 -0
- package/src/components/ui/widgets/MapFiltersButton.js +104 -0
- package/src/components/ui/widgets/MapLayersButton.js +79 -0
- package/src/components/ui/widgets/OSMEditors.js +155 -0
- package/src/components/ui/widgets/PictureLegendActions.js +117 -0
- package/src/components/ui/widgets/Player.css +7 -0
- package/src/components/ui/widgets/Player.js +151 -0
- package/src/components/ui/widgets/Zoom.js +82 -0
- package/src/components/ui/widgets/index.js +13 -0
- package/src/img/loader_base.jpg +0 -0
- package/src/img/panoramax.svg +13 -0
- package/src/img/switch_big.svg +20 -10
- package/src/index.js +7 -9
- package/src/translations/br.json +1 -0
- package/src/translations/da.json +38 -15
- package/src/translations/de.json +5 -3
- package/src/translations/en.json +35 -15
- package/src/translations/eo.json +38 -15
- package/src/translations/es.json +1 -1
- package/src/translations/fr.json +36 -16
- package/src/translations/hu.json +1 -1
- package/src/translations/it.json +39 -16
- package/src/translations/ja.json +182 -1
- package/src/translations/nl.json +106 -6
- package/src/translations/pl.json +1 -1
- package/src/translations/sv.json +182 -0
- package/src/translations/zh_Hant.json +35 -14
- package/src/utils/API.js +109 -49
- package/src/utils/InitParameters.js +388 -0
- package/src/utils/PhotoAdapter.js +1 -0
- package/src/utils/URLHandler.js +362 -0
- package/src/utils/geocoder.js +152 -0
- package/src/utils/{I18n.js → i18n.js} +7 -3
- package/src/utils/index.js +11 -0
- package/src/utils/{Map.js → map.js} +256 -77
- package/src/utils/picture.js +442 -0
- package/src/utils/utils.js +324 -0
- package/src/utils/widgets.js +55 -0
- package/tests/components/core/Basic.test.js +121 -0
- package/tests/components/core/BasicMock.js +25 -0
- package/tests/components/core/CoverageMap.test.js +20 -0
- package/tests/components/core/Editor.test.js +20 -0
- package/tests/components/core/PhotoViewer.test.js +57 -0
- package/tests/components/core/Viewer.test.js +84 -0
- package/tests/components/core/__snapshots__/PhotoViewer.test.js.snap +73 -0
- package/tests/components/core/__snapshots__/Viewer.test.js.snap +145 -0
- package/tests/components/ui/CopyButton.test.js +52 -0
- package/tests/components/ui/Loader.test.js +55 -0
- package/tests/components/{Map.test.js → ui/Map.test.js} +73 -61
- package/tests/components/{Photo.test.js → ui/Photo.test.js} +97 -63
- package/tests/components/ui/Popup.test.js +26 -0
- package/tests/components/ui/QualityScore.test.js +18 -0
- package/tests/components/ui/SearchBar.test.js +110 -0
- package/tests/components/ui/__snapshots__/CopyButton.test.js.snap +33 -0
- package/tests/components/ui/__snapshots__/Loader.test.js.snap +56 -0
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Map.test.js.snap +11 -38
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Photo.test.js.snap +70 -6
- package/tests/components/ui/__snapshots__/Popup.test.js.snap +29 -0
- package/tests/components/ui/__snapshots__/QualityScore.test.js.snap +11 -0
- package/tests/components/ui/__snapshots__/SearchBar.test.js.snap +65 -0
- package/tests/utils/API.test.js +83 -83
- package/tests/utils/InitParameters.test.js +499 -0
- package/tests/utils/URLHandler.test.js +401 -0
- package/tests/utils/__snapshots__/API.test.js.snap +10 -0
- package/tests/utils/__snapshots__/URLHandler.test.js.snap +21 -0
- package/tests/utils/__snapshots__/{Map.test.js.snap → geocoder.test.js.snap} +1 -1
- package/tests/utils/__snapshots__/map.test.js.snap +11 -0
- package/tests/utils/__snapshots__/picture.test.js.snap +327 -0
- package/tests/utils/__snapshots__/widgets.test.js.snap +19 -0
- package/tests/utils/geocoder.test.js +37 -0
- package/tests/utils/{I18n.test.js → i18n.test.js} +8 -8
- package/tests/utils/map.test.js +126 -0
- package/tests/utils/picture.test.js +745 -0
- package/tests/utils/utils.test.js +288 -0
- package/tests/utils/widgets.test.js +31 -0
- package/docs/01_Start.md +0 -149
- package/docs/02_Usage.md +0 -831
- package/docs/04_Advanced_examples.md +0 -216
- package/src/Editor.css +0 -37
- package/src/Editor.js +0 -361
- package/src/StandaloneMap.js +0 -114
- package/src/Viewer.css +0 -203
- package/src/Viewer.js +0 -1246
- package/src/components/CoreView.css +0 -70
- package/src/components/CoreView.js +0 -175
- package/src/components/Loader.css +0 -74
- package/src/components/Loader.js +0 -120
- package/src/img/loader_hd.jpg +0 -0
- package/src/utils/Exif.js +0 -193
- package/src/utils/Utils.js +0 -631
- package/src/utils/Widgets.js +0 -562
- package/src/viewer/URLHash.js +0 -469
- package/src/viewer/Widgets.css +0 -880
- package/src/viewer/Widgets.js +0 -1470
- package/tests/Editor.test.js +0 -126
- package/tests/StandaloneMap.test.js +0 -45
- package/tests/Viewer.test.js +0 -366
- package/tests/__snapshots__/Editor.test.js.snap +0 -298
- package/tests/__snapshots__/StandaloneMap.test.js.snap +0 -30
- package/tests/__snapshots__/Viewer.test.js.snap +0 -195
- package/tests/components/CoreView.test.js +0 -92
- package/tests/components/Loader.test.js +0 -38
- package/tests/components/__snapshots__/Loader.test.js.snap +0 -15
- package/tests/utils/Exif.test.js +0 -124
- package/tests/utils/Map.test.js +0 -113
- package/tests/utils/Utils.test.js +0 -300
- package/tests/utils/Widgets.test.js +0 -107
- package/tests/utils/__snapshots__/Exif.test.js.snap +0 -43
- package/tests/utils/__snapshots__/Utils.test.js.snap +0 -41
- package/tests/utils/__snapshots__/Widgets.test.js.snap +0 -44
- package/tests/viewer/URLHash.test.js +0 -559
- package/tests/viewer/Widgets.test.js +0 -127
- package/tests/viewer/__snapshots__/URLHash.test.js.snap +0 -108
- package/tests/viewer/__snapshots__/Widgets.test.js.snap +0 -403
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import "./Photo.css";
|
|
2
|
-
import LoaderImgBase from "
|
|
3
|
-
import LogoDead from "
|
|
2
|
+
import LoaderImgBase from "../../img/loader_base.jpg";
|
|
3
|
+
import LogoDead from "../../img/logo_dead.svg";
|
|
4
4
|
import {
|
|
5
5
|
getDistance, positionToXYZ, xyzToPosition,
|
|
6
|
-
|
|
7
|
-
} from "
|
|
6
|
+
getRelativeHeading, BASE_PANORAMA_ID, isNullId,
|
|
7
|
+
} from "../../utils/utils";
|
|
8
|
+
import { apiFeatureToPSVNode } from "../../utils/picture";
|
|
8
9
|
|
|
9
10
|
// Photo Sphere Viewer imports
|
|
10
11
|
import "@photo-sphere-viewer/core/index.css";
|
|
@@ -13,7 +14,7 @@ import "@photo-sphere-viewer/gallery-plugin/index.css";
|
|
|
13
14
|
import "@photo-sphere-viewer/markers-plugin/index.css";
|
|
14
15
|
import { Viewer as PSViewer } from "@photo-sphere-viewer/core";
|
|
15
16
|
import { VirtualTourPlugin } from "@photo-sphere-viewer/virtual-tour-plugin";
|
|
16
|
-
import PhotoAdapter from "
|
|
17
|
+
import PhotoAdapter from "../../utils/PhotoAdapter";
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
// Default panorama (logo)
|
|
@@ -36,23 +37,48 @@ const BASE_PANORAMA_NODE = {
|
|
|
36
37
|
properties: {},
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
export const PSV_DEFAULT_ZOOM = 30;
|
|
40
|
+
export const PSV_DEFAULT_ZOOM = 30; // eslint-disable-line import/no-unused-modules
|
|
40
41
|
export const PSV_ANIM_DURATION = 250;
|
|
41
42
|
export const PIC_MAX_STAY_DURATION = 3000;
|
|
42
43
|
|
|
43
44
|
PSViewer.useNewAnglesOrder = true;
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Triggered once when the panorama image has been loaded and the viewer is ready to perform the first render.
|
|
48
|
+
* @see {@link https://photo-sphere-viewer.js.org/guide/events.html#ready|Photo Sphere Viewer documentation}
|
|
49
|
+
* @event Panoramax.components.ui.Photo#ready
|
|
50
|
+
* @memberof Panoramax.components.ui.Photo
|
|
51
|
+
* @type {Event}
|
|
52
|
+
*/
|
|
53
|
+
|
|
45
54
|
/**
|
|
46
55
|
* Photo is the component showing a single picture.
|
|
47
56
|
* It uses Photo Sphere Viewer as a basis, and pre-configure dialog with STAC API.
|
|
48
57
|
*
|
|
49
58
|
* Note that all functions of [PhotoSphereViewer Viewer class](https://photo-sphere-viewer.js.org/api/classes/core.viewer) are available as well.
|
|
50
59
|
*
|
|
51
|
-
* @
|
|
60
|
+
* @class Panoramax.components.ui.Photo
|
|
61
|
+
* @extends [photo-sphere-viewer.core.Viewer](https://photo-sphere-viewer.js.org/api/classes/Core.Viewer.html)
|
|
62
|
+
* @param {Panoramax.components.core.basic} parent The parent view
|
|
52
63
|
* @param {Element} container The DOM element to create into
|
|
53
64
|
* @param {object} [options] The viewer options. Can be any of [Photo Sphere Viewer options](https://photo-sphere-viewer.js.org/guide/config.html#standard-options)
|
|
54
65
|
* @param {number} [options.transitionDuration] The number of milliseconds the transition animation should be.
|
|
66
|
+
* @param {number[]} [options.position] Initial geographical coordinates (as [latitude, longitude]) to find picture nearby. Only used if no picture ID is set.
|
|
55
67
|
* @param {function} [options.shouldGoFast] Function returning a boolean to indicate if we may skip loading HD images.
|
|
68
|
+
* @param {string} [options.picturesNavigation=any] The allowed pictures navigation ("any": no restriction, "seq": only pictures in same sequence, "pic": only selected picture)
|
|
69
|
+
* @fires Panoramax.components.ui.Photo#picture-loading
|
|
70
|
+
* @fires Panoramax.components.ui.Photo#picture-preview-started
|
|
71
|
+
* @fires Panoramax.components.ui.Photo#picture-preview-stopped
|
|
72
|
+
* @fires Panoramax.components.ui.Photo#view-rotated
|
|
73
|
+
* @fires Panoramax.components.ui.Photo#picture-loaded
|
|
74
|
+
* @fires Panoramax.components.ui.Photo#picture-tiles-loaded
|
|
75
|
+
* @fires Panoramax.components.ui.Photo#transition-duration-changed
|
|
76
|
+
* @fires Panoramax.components.ui.Photo#sequence-playing
|
|
77
|
+
* @fires Panoramax.components.ui.Photo#sequence-stopped
|
|
78
|
+
* @fires Panoramax.components.ui.Photo#pictures-navigation-changed
|
|
79
|
+
* @fires Panoramax.components.ui.Photo#ready
|
|
80
|
+
* @example
|
|
81
|
+
* const psv = new Panoramax.components.ui.Photo(viewer, psvNode, {transitionDuration: 500})
|
|
56
82
|
*/
|
|
57
83
|
export default class Photo extends PSViewer {
|
|
58
84
|
constructor(parent, container, options = {}) {
|
|
@@ -64,8 +90,8 @@ export default class Photo extends PSViewer {
|
|
|
64
90
|
resolution: parent.isWidthSmall() ? 32 : 64,
|
|
65
91
|
shouldGoFast: options.shouldGoFast,
|
|
66
92
|
}],
|
|
67
|
-
withCredentials: parent
|
|
68
|
-
requestHeaders: parent
|
|
93
|
+
withCredentials: parent?.fetchOptions?.credentials == "include",
|
|
94
|
+
requestHeaders: parent?.fetchOptions?.headers,
|
|
69
95
|
panorama: BASE_PANORAMA,
|
|
70
96
|
lang: parent._t.psv,
|
|
71
97
|
minFov: 5,
|
|
@@ -91,7 +117,8 @@ export default class Photo extends PSViewer {
|
|
|
91
117
|
});
|
|
92
118
|
|
|
93
119
|
this._parent = parent;
|
|
94
|
-
|
|
120
|
+
this._options = options;
|
|
121
|
+
container.classList.add("pnx-psv");
|
|
95
122
|
this._shouldGoFast = options?.shouldGoFast || (() => false);
|
|
96
123
|
this._transitionDuration = options?.transitionDuration || PSV_ANIM_DURATION;
|
|
97
124
|
this._myVTour = this.getPlugin(VirtualTourPlugin);
|
|
@@ -99,6 +126,8 @@ export default class Photo extends PSViewer {
|
|
|
99
126
|
this._myVTour.config.transitionOptions = this._psvNodeTransition.bind(this);
|
|
100
127
|
this._clearArrows = this._myVTour.arrowsRenderer.clear.bind(this._myVTour.arrowsRenderer);
|
|
101
128
|
this._myVTour.arrowsRenderer.clear = () => {};
|
|
129
|
+
this._sequencePlaying = false;
|
|
130
|
+
this._picturesNavigation = this._options.picturesNavigation || "any";
|
|
102
131
|
|
|
103
132
|
// Cache to find sequence ID for a single picture
|
|
104
133
|
this._picturesSequences = {};
|
|
@@ -119,6 +148,11 @@ export default class Photo extends PSViewer {
|
|
|
119
148
|
this.loader.thickness = 10;
|
|
120
149
|
this.loader.canvas.setAttribute("viewBox", "0 0 150 150");
|
|
121
150
|
this.loader.__updateContent();
|
|
151
|
+
|
|
152
|
+
// Handle initial parameters
|
|
153
|
+
if(this._options.position && !this._parent.picture) {
|
|
154
|
+
this.goToPosition(...this._options.position);
|
|
155
|
+
}
|
|
122
156
|
}
|
|
123
157
|
|
|
124
158
|
/**
|
|
@@ -127,20 +161,21 @@ export default class Photo extends PSViewer {
|
|
|
127
161
|
* @private
|
|
128
162
|
* @param {string} picId The picture UUID
|
|
129
163
|
* @returns {Promise} Resolves on PSV node metadata
|
|
164
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
130
165
|
*/
|
|
131
166
|
async _getNodeFromAPI(picId) {
|
|
132
|
-
if(
|
|
167
|
+
if(isNullId(picId)) { return BASE_PANORAMA_NODE; }
|
|
133
168
|
|
|
134
169
|
const picApiResponse = await fetch(
|
|
135
|
-
this._parent.
|
|
136
|
-
this._parent.
|
|
170
|
+
this._parent.api.getPictureMetadataUrl(picId, this._picturesSequences[picId]),
|
|
171
|
+
this._parent.api._getFetchOptions()
|
|
137
172
|
);
|
|
138
173
|
let metadata = await picApiResponse.json();
|
|
139
174
|
|
|
140
175
|
if(metadata.features) { metadata = metadata.features.pop(); }
|
|
141
176
|
if(!metadata || Object.keys(metadata).length === 0 || !picApiResponse.ok) {
|
|
142
|
-
if(this._parent.
|
|
143
|
-
this._parent.
|
|
177
|
+
if(this._parent.loader) {
|
|
178
|
+
this._parent.loader.dismiss(true, this._parent._t.pnx.error_pic);
|
|
144
179
|
}
|
|
145
180
|
throw new Error("Picture with ID " + picId + " was not found");
|
|
146
181
|
}
|
|
@@ -150,7 +185,7 @@ export default class Photo extends PSViewer {
|
|
|
150
185
|
metadata,
|
|
151
186
|
this._parent._t,
|
|
152
187
|
this._parent._isInternetFast,
|
|
153
|
-
this.
|
|
188
|
+
this._picturesNavFilter.bind(this)
|
|
154
189
|
);
|
|
155
190
|
if(node?.sequence?.prevPic) { this._picturesSequences[node?.sequence?.prevPic] = metadata.collection; }
|
|
156
191
|
if(node?.sequence?.nextPic) { this._picturesSequences[node?.sequence?.nextPic] = metadata.collection; }
|
|
@@ -164,6 +199,7 @@ export default class Photo extends PSViewer {
|
|
|
164
199
|
* @param {*} [fromNode] Currently shown node (previous)
|
|
165
200
|
* @param {*} [fromLink] Link clicked by user to go from current to next node
|
|
166
201
|
* @private
|
|
202
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
167
203
|
*/
|
|
168
204
|
_psvNodeTransition(toNode, fromNode, fromLink) {
|
|
169
205
|
let nodeTransition = {};
|
|
@@ -174,14 +210,16 @@ export default class Photo extends PSViewer {
|
|
|
174
210
|
const sameSequence = fromNode && toNode.sequence.id === fromNode.sequence.id;
|
|
175
211
|
const fromNodeHeading = (fromNode?.properties?.["view:azimuth"] || 0) * (Math.PI / 180);
|
|
176
212
|
const toNodeHeading = (toNode?.properties?.["view:azimuth"] || 0) * (Math.PI / 180);
|
|
213
|
+
const toNodeRelHeading = getRelativeHeading(toNode) * (Math.PI / 180);
|
|
177
214
|
|
|
178
215
|
this.setOption("maxFov", Math.min(toNode.horizontalFov * 3/4, 90));
|
|
179
216
|
|
|
180
|
-
const
|
|
217
|
+
const forwardNoAnim = {
|
|
218
|
+
showLoader: false,
|
|
219
|
+
effect: "none",
|
|
181
220
|
speed: 0,
|
|
182
|
-
fadeIn: false,
|
|
183
221
|
rotation: false,
|
|
184
|
-
rotateTo: { pitch: 0, yaw:
|
|
222
|
+
rotateTo: { pitch: 0, yaw: -toNodeRelHeading },
|
|
185
223
|
zoomTo: PSV_DEFAULT_ZOOM
|
|
186
224
|
};
|
|
187
225
|
|
|
@@ -189,19 +227,19 @@ export default class Photo extends PSViewer {
|
|
|
189
227
|
if(toNode.horizontalFov == 360) {
|
|
190
228
|
// No previous sequence -> Point to center + no animation
|
|
191
229
|
if(!fromNode) {
|
|
192
|
-
nodeTransition =
|
|
230
|
+
nodeTransition = forwardNoAnim;
|
|
193
231
|
}
|
|
194
232
|
// Has a previous sequence
|
|
195
233
|
else {
|
|
196
234
|
// Far away sequences -> Point to center + no animation
|
|
197
235
|
if(getDistance(fromNode.gps, toNode.gps) >= 0.001) {
|
|
198
|
-
nodeTransition =
|
|
236
|
+
nodeTransition = forwardNoAnim;
|
|
199
237
|
}
|
|
200
238
|
// Nearby sequences -> Keep orientation
|
|
201
239
|
else {
|
|
202
240
|
nodeTransition = {
|
|
203
241
|
speed: animationDuration,
|
|
204
|
-
|
|
242
|
+
effect: following && animated ? "fade" : "none",
|
|
205
243
|
rotation: following && sameSequence && animated,
|
|
206
244
|
rotateTo: this.getPosition()
|
|
207
245
|
};
|
|
@@ -220,7 +258,7 @@ export default class Photo extends PSViewer {
|
|
|
220
258
|
const notTooMuchRotation = Math.abs(fromNodeHeading - toNodeHeading) <= Math.PI / 4;
|
|
221
259
|
nodeTransition = {
|
|
222
260
|
speed: animationDuration,
|
|
223
|
-
|
|
261
|
+
effect: following && notTooMuchRotation && animated ? "fade" : "none",
|
|
224
262
|
rotation: following && notTooMuchRotation && animated,
|
|
225
263
|
rotateTo: keepZoomPos ? this.getPosition() : { pitch: 0, yaw: 0 },
|
|
226
264
|
zoomTo: keepZoomPos ? this.getZoomLevel() : PSV_DEFAULT_ZOOM,
|
|
@@ -228,11 +266,11 @@ export default class Photo extends PSViewer {
|
|
|
228
266
|
}
|
|
229
267
|
// Different sequence -> Point to center + no animation
|
|
230
268
|
else {
|
|
231
|
-
nodeTransition =
|
|
269
|
+
nodeTransition = forwardNoAnim;
|
|
232
270
|
}
|
|
233
271
|
}
|
|
234
272
|
|
|
235
|
-
if(nodeTransition.
|
|
273
|
+
if(nodeTransition.effect === "fade" && nodeTransition.speed >= 150) {
|
|
236
274
|
setTimeout(this._clearArrows, nodeTransition.speed-100);
|
|
237
275
|
}
|
|
238
276
|
else {
|
|
@@ -243,18 +281,17 @@ export default class Photo extends PSViewer {
|
|
|
243
281
|
/**
|
|
244
282
|
* Event for picture starting to load
|
|
245
283
|
*
|
|
246
|
-
* @event
|
|
247
|
-
* @
|
|
248
|
-
* @type {object}
|
|
249
|
-
* @property {object} detail Event information
|
|
284
|
+
* @event Panoramax.components.ui.Photo#picture-loading
|
|
285
|
+
* @type {CustomEvent}
|
|
250
286
|
* @property {string} detail.picId The picture unique identifier
|
|
251
287
|
* @property {number} detail.lon Longitude (WGS84)
|
|
252
288
|
* @property {number} detail.lat Latitude (WGS84)
|
|
253
289
|
* @property {number} detail.x New x position (in degrees, 0-360), corresponds to heading (0° = North, 90° = East, 180° = South, 270° = West)
|
|
254
290
|
* @property {number} detail.y New y position (in degrees)
|
|
255
291
|
* @property {number} detail.z New z position (0-100)
|
|
292
|
+
* @property {boolean} detail.first True if first picture loaded
|
|
256
293
|
*/
|
|
257
|
-
const event = new CustomEvent("
|
|
294
|
+
const event = new CustomEvent("picture-loading", {
|
|
258
295
|
detail: {
|
|
259
296
|
...Object.assign({},
|
|
260
297
|
this.getXYZ(),
|
|
@@ -263,10 +300,11 @@ export default class Photo extends PSViewer {
|
|
|
263
300
|
),
|
|
264
301
|
picId: toNode.id,
|
|
265
302
|
lon: toNode.gps[0],
|
|
266
|
-
lat: toNode.gps[1]
|
|
303
|
+
lat: toNode.gps[1],
|
|
304
|
+
first: this._parent._initParams?.getParentPostInit().picture == toNode.id,
|
|
267
305
|
}
|
|
268
306
|
});
|
|
269
|
-
this.
|
|
307
|
+
this.dispatchEvent(event);
|
|
270
308
|
|
|
271
309
|
return nodeTransition;
|
|
272
310
|
}
|
|
@@ -276,6 +314,7 @@ export default class Photo extends PSViewer {
|
|
|
276
314
|
* It creates a custom event "picture-preview-started"
|
|
277
315
|
* @private
|
|
278
316
|
* @param {object} e The event data
|
|
317
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
279
318
|
*/
|
|
280
319
|
_onEnterArrow(e) {
|
|
281
320
|
const fromLink = e.link;
|
|
@@ -295,20 +334,18 @@ export default class Photo extends PSViewer {
|
|
|
295
334
|
/**
|
|
296
335
|
* Event for picture preview
|
|
297
336
|
*
|
|
298
|
-
* @event
|
|
299
|
-
* @
|
|
300
|
-
* @type {object}
|
|
301
|
-
* @property {object} detail Event information
|
|
337
|
+
* @event Panoramax.components.ui.Photo#picture-preview-started
|
|
338
|
+
* @type {CustomEvent}
|
|
302
339
|
* @property {string} detail.picId The picture ID
|
|
303
340
|
* @property {number[]} detail.coordinates [x,y] coordinates
|
|
304
341
|
* @property {number} detail.direction The theorical picture orientation
|
|
305
342
|
*/
|
|
306
|
-
const event = new CustomEvent("
|
|
343
|
+
const event = new CustomEvent("picture-preview-started", { detail: {
|
|
307
344
|
picId: fromLink.nodeId,
|
|
308
345
|
coordinates: fromLink.gps,
|
|
309
346
|
direction,
|
|
310
347
|
}});
|
|
311
|
-
this.
|
|
348
|
+
this.dispatchEvent(event);
|
|
312
349
|
}
|
|
313
350
|
|
|
314
351
|
/**
|
|
@@ -316,47 +353,44 @@ export default class Photo extends PSViewer {
|
|
|
316
353
|
* It creates a custom event "picture-preview-stopped"
|
|
317
354
|
* @private
|
|
318
355
|
* @param {object} e The event data
|
|
356
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
319
357
|
*/
|
|
320
358
|
_onLeaveArrow(e) {
|
|
321
359
|
const fromLink = e.link;
|
|
322
360
|
|
|
323
361
|
/**
|
|
324
362
|
* Event for end of picture preview
|
|
325
|
-
*
|
|
326
|
-
* @
|
|
327
|
-
* @memberof CoreView
|
|
328
|
-
* @type {object}
|
|
329
|
-
* @property {object} detail Event information
|
|
363
|
+
* @event Panoramax.components.ui.Photo#picture-preview-stopped
|
|
364
|
+
* @type {CustomEvent}
|
|
330
365
|
* @property {string} detail.picId The picture ID
|
|
331
366
|
*/
|
|
332
|
-
const event = new CustomEvent("
|
|
367
|
+
const event = new CustomEvent("picture-preview-stopped", { detail: {
|
|
333
368
|
picId: fromLink.nodeId,
|
|
334
369
|
}});
|
|
335
|
-
this.
|
|
370
|
+
this.dispatchEvent(event);
|
|
336
371
|
}
|
|
337
372
|
|
|
338
373
|
/**
|
|
339
374
|
* Event handler for position update in PSV.
|
|
340
375
|
* Allows to send a custom "view-rotated" event.
|
|
341
376
|
* @private
|
|
377
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
342
378
|
*/
|
|
343
379
|
_onPositionUpdated({position}) {
|
|
344
380
|
const pos = positionToXYZ(position, this.getZoomLevel());
|
|
345
381
|
pos.x += this.getPictureOriginalHeading();
|
|
346
382
|
pos.x = pos.x % 360;
|
|
383
|
+
|
|
347
384
|
/**
|
|
348
385
|
* Event for viewer rotation
|
|
349
|
-
*
|
|
350
|
-
* @
|
|
351
|
-
* @memberof CoreView
|
|
352
|
-
* @type {object}
|
|
353
|
-
* @property {object} detail Event information
|
|
386
|
+
* @event Panoramax.components.ui.Photo#view-rotated
|
|
387
|
+
* @type {CustomEvent}
|
|
354
388
|
* @property {number} detail.x New x position (in degrees, 0-360), corresponds to heading (0° = North, 90° = East, 180° = South, 270° = West)
|
|
355
389
|
* @property {number} detail.y New y position (in degrees)
|
|
356
390
|
* @property {number} detail.z New Z position (between 0 and 100)
|
|
357
391
|
*/
|
|
358
|
-
const event = new CustomEvent("
|
|
359
|
-
this.
|
|
392
|
+
const event = new CustomEvent("view-rotated", { detail: pos });
|
|
393
|
+
this.dispatchEvent(event);
|
|
360
394
|
|
|
361
395
|
this._onTilesStartLoading();
|
|
362
396
|
}
|
|
@@ -365,57 +399,59 @@ export default class Photo extends PSViewer {
|
|
|
365
399
|
* Event handler for zoom updates in PSV.
|
|
366
400
|
* Allows to send a custom "view-rotated" event.
|
|
367
401
|
* @private
|
|
402
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
368
403
|
*/
|
|
369
404
|
_onZoomUpdated({zoomLevel}) {
|
|
370
|
-
const event = new CustomEvent("
|
|
371
|
-
this.
|
|
405
|
+
const event = new CustomEvent("view-rotated", { detail: { ...this.getXY(), z: zoomLevel} });
|
|
406
|
+
this.dispatchEvent(event);
|
|
372
407
|
|
|
373
408
|
this._onTilesStartLoading();
|
|
374
409
|
}
|
|
375
410
|
|
|
376
411
|
/**
|
|
377
412
|
* Event handler for node change in PSV.
|
|
378
|
-
* Allows to send a custom "
|
|
413
|
+
* Allows to send a custom "picture-loaded" event.
|
|
379
414
|
* @private
|
|
415
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
380
416
|
*/
|
|
381
417
|
_onNodeChanged(e) {
|
|
382
418
|
// Clean up clicked arrows
|
|
383
|
-
for(let d of document.getElementsByClassName("
|
|
384
|
-
d.classList.remove("
|
|
419
|
+
for(let d of document.getElementsByClassName("pnx-psv-tour-arrows")) {
|
|
420
|
+
d.classList.remove("pnx-clicked");
|
|
385
421
|
}
|
|
386
422
|
|
|
387
423
|
if(e.node.id) {
|
|
424
|
+
const isFirst = this._parent._initParams?.getParentPostInit().picture == e.node.id;
|
|
388
425
|
this._parent.select(e.node?.sequence?.id, e.node.id);
|
|
389
426
|
const picMeta = this.getPictureMetadata();
|
|
390
427
|
if(!picMeta) {
|
|
391
|
-
this.
|
|
428
|
+
this.dispatchEvent(new CustomEvent("picture-loaded", {detail: {}}));
|
|
392
429
|
return;
|
|
393
430
|
}
|
|
394
431
|
this._prevSequence = picMeta.sequence.id;
|
|
395
432
|
|
|
396
433
|
/**
|
|
397
434
|
* Event for picture load (low-resolution image is loaded)
|
|
398
|
-
*
|
|
399
|
-
* @
|
|
400
|
-
* @memberof CoreView
|
|
401
|
-
* @type {object}
|
|
402
|
-
* @property {object} detail Event information
|
|
435
|
+
* @event Panoramax.components.ui.Photo#picture-loaded
|
|
436
|
+
* @type {CustomEvent}
|
|
403
437
|
* @property {string} detail.picId The picture unique identifier
|
|
404
438
|
* @property {number} detail.lon Longitude (WGS84)
|
|
405
439
|
* @property {number} detail.lat Latitude (WGS84)
|
|
406
440
|
* @property {number} detail.x New x position (in degrees, 0-360), corresponds to heading (0° = North, 90° = East, 180° = South, 270° = West)
|
|
407
441
|
* @property {number} detail.y New y position (in degrees)
|
|
408
442
|
* @property {number} detail.z New z position (0-100)
|
|
443
|
+
* @property {boolean} detail.first True if first picture loaded
|
|
409
444
|
*/
|
|
410
|
-
const event = new CustomEvent("
|
|
445
|
+
const event = new CustomEvent("picture-loaded", {
|
|
411
446
|
detail: {
|
|
412
447
|
...this.getXYZ(),
|
|
413
448
|
picId: e.node.id,
|
|
414
449
|
lon: picMeta.gps[0],
|
|
415
|
-
lat: picMeta.gps[1]
|
|
416
|
-
|
|
450
|
+
lat: picMeta.gps[1],
|
|
451
|
+
first: isFirst
|
|
452
|
+
},
|
|
417
453
|
});
|
|
418
|
-
this.
|
|
454
|
+
this.dispatchEvent(event);
|
|
419
455
|
|
|
420
456
|
// Change download URL
|
|
421
457
|
if(picMeta.panorama.hdUrl) {
|
|
@@ -432,7 +468,7 @@ export default class Photo extends PSViewer {
|
|
|
432
468
|
|
|
433
469
|
/**
|
|
434
470
|
* Event handler for loading a new range of tiles
|
|
435
|
-
*
|
|
471
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
436
472
|
* @private
|
|
437
473
|
*/
|
|
438
474
|
_onTilesStartLoading() {
|
|
@@ -445,15 +481,12 @@ export default class Photo extends PSViewer {
|
|
|
445
481
|
if(this._myVTour.state.currentNode) {
|
|
446
482
|
/**
|
|
447
483
|
* Event launched when all visible tiles of a picture are loaded
|
|
448
|
-
*
|
|
449
|
-
* @
|
|
450
|
-
* @memberof CoreView
|
|
451
|
-
* @type {object}
|
|
452
|
-
* @property {object} detail Event information
|
|
484
|
+
* @event Panoramax.components.ui.Photo#picture-tiles-loaded
|
|
485
|
+
* @type {CustomEvent}
|
|
453
486
|
* @property {string} detail.picId The picture unique identifier
|
|
454
487
|
*/
|
|
455
|
-
const event = new
|
|
456
|
-
this.
|
|
488
|
+
const event = new CustomEvent("picture-tiles-loaded", { detail: { picId: this._myVTour.state.currentNode.id }});
|
|
489
|
+
this.dispatchEvent(event);
|
|
457
490
|
}
|
|
458
491
|
clearInterval(this._tilesQueueTimer);
|
|
459
492
|
delete this._tilesQueueTimer;
|
|
@@ -463,17 +496,28 @@ export default class Photo extends PSViewer {
|
|
|
463
496
|
|
|
464
497
|
/**
|
|
465
498
|
* Access currently shown picture metadata
|
|
466
|
-
*
|
|
499
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
467
500
|
* @returns {object} Picture metadata
|
|
468
501
|
*/
|
|
469
502
|
getPictureMetadata() {
|
|
470
|
-
if(this._myVTour?.state?.currentNode?.id
|
|
503
|
+
if(isNullId(this._myVTour?.state?.currentNode?.id)) { return null; }
|
|
471
504
|
return this._myVTour.state.currentNode ? Object.assign({}, this._myVTour.state.currentNode) : null;
|
|
472
505
|
}
|
|
473
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Get current picture ID, or loading picture ID if any.
|
|
509
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
510
|
+
* @returns {string|null} Picture ID (current or loading), or null if none is selected.
|
|
511
|
+
*/
|
|
512
|
+
getPictureId() {
|
|
513
|
+
const id = this._myVTour?.state?.loadingNode || this._myVTour?.state?.currentNode?.id;
|
|
514
|
+
return isNullId(id) ? null : id;
|
|
515
|
+
}
|
|
516
|
+
|
|
474
517
|
/**
|
|
475
518
|
* Handler for select event.
|
|
476
519
|
* @private
|
|
520
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
477
521
|
*/
|
|
478
522
|
_onSelect(e) {
|
|
479
523
|
if(e.detail.seqId) {
|
|
@@ -483,13 +527,15 @@ export default class Photo extends PSViewer {
|
|
|
483
527
|
if(this._myVTour.getCurrentNode()?.id !== e.detail.picId) {
|
|
484
528
|
this.loader.show();
|
|
485
529
|
this._myVTour.setCurrentNode(e.detail.picId).catch(e => {
|
|
486
|
-
this.showErrorOverlay(e, this._parent._t.
|
|
530
|
+
this.showErrorOverlay(e, this._parent._t.pnx.error_pic, true);
|
|
487
531
|
});
|
|
488
532
|
}
|
|
489
533
|
}
|
|
490
534
|
|
|
491
535
|
/**
|
|
492
536
|
* Displays next picture in current sequence (if any)
|
|
537
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
538
|
+
* @throws {Error} If no picture is selected, or no next picture available
|
|
493
539
|
*/
|
|
494
540
|
goToNextPicture() {
|
|
495
541
|
if(!this.getPictureMetadata()) {
|
|
@@ -507,6 +553,8 @@ export default class Photo extends PSViewer {
|
|
|
507
553
|
|
|
508
554
|
/**
|
|
509
555
|
* Displays previous picture in current sequence (if any)
|
|
556
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
557
|
+
* @throws {Error} If no picture is selected, or no previous picture available
|
|
510
558
|
*/
|
|
511
559
|
goToPrevPicture() {
|
|
512
560
|
if(!this.getPictureMetadata()) {
|
|
@@ -524,13 +572,15 @@ export default class Photo extends PSViewer {
|
|
|
524
572
|
|
|
525
573
|
/**
|
|
526
574
|
* Displays in viewer a picture near to given coordinates
|
|
527
|
-
*
|
|
575
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
528
576
|
* @param {number} lat Latitude (WGS84)
|
|
529
577
|
* @param {number} lon Longitude (WGS84)
|
|
530
|
-
* @returns {Promise}
|
|
578
|
+
* @returns {Promise}
|
|
579
|
+
* @fulfil {string} Picture ID if picture found
|
|
580
|
+
* @reject {Error} If no picture found
|
|
531
581
|
*/
|
|
532
582
|
async goToPosition(lat, lon) {
|
|
533
|
-
return this._parent.
|
|
583
|
+
return this._parent.api.getPicturesAroundCoordinates(lat, lon)
|
|
534
584
|
.then(res => {
|
|
535
585
|
if(res.features.length > 0) {
|
|
536
586
|
const f = res.features.pop();
|
|
@@ -548,7 +598,7 @@ export default class Photo extends PSViewer {
|
|
|
548
598
|
|
|
549
599
|
/**
|
|
550
600
|
* Get 2D position of sphere currently shown to user
|
|
551
|
-
*
|
|
601
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
552
602
|
* @returns {object} Position in format { x: heading in degrees (0° = North, 90° = East, 180° = South, 270° = West), y: top/bottom position in degrees (-90° = bottom, 0° = front, 90° = top) }
|
|
553
603
|
*/
|
|
554
604
|
getXY() {
|
|
@@ -559,7 +609,7 @@ export default class Photo extends PSViewer {
|
|
|
559
609
|
|
|
560
610
|
/**
|
|
561
611
|
* Get 3D position of sphere currently shown to user
|
|
562
|
-
*
|
|
612
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
563
613
|
* @returns {object} Position in format { x: heading in degrees (0° = North, 90° = East, 180° = South, 270° = West), y: top/bottom position in degrees (-90° = bottom, 0° = front, 90° = top), z: zoom (0 = wide, 100 = zoomed in) }
|
|
564
614
|
*/
|
|
565
615
|
getXYZ() {
|
|
@@ -570,7 +620,8 @@ export default class Photo extends PSViewer {
|
|
|
570
620
|
|
|
571
621
|
/**
|
|
572
622
|
* Get capture orientation of current picture, based on its GPS.
|
|
573
|
-
* @returns Picture original heading in degrees (0 to 360°)
|
|
623
|
+
* @returns {number} Picture original heading in degrees (0 to 360°)
|
|
624
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
574
625
|
*/
|
|
575
626
|
getPictureOriginalHeading() {
|
|
576
627
|
return this.getPictureMetadata()?.properties?.["view:azimuth"] || 0;
|
|
@@ -579,8 +630,8 @@ export default class Photo extends PSViewer {
|
|
|
579
630
|
/**
|
|
580
631
|
* Computes the relative heading of currently selected picture.
|
|
581
632
|
* This gives the angle of capture compared to sequence path (vehicle movement).
|
|
582
|
-
*
|
|
583
|
-
* @returns Relative heading in degrees (-180 to 180)
|
|
633
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
634
|
+
* @returns {number} Relative heading in degrees (-180 to 180)
|
|
584
635
|
*/
|
|
585
636
|
getPictureRelativeHeading() {
|
|
586
637
|
return getRelativeHeading(this.getPictureMetadata());
|
|
@@ -589,6 +640,7 @@ export default class Photo extends PSViewer {
|
|
|
589
640
|
/**
|
|
590
641
|
* Clears the Photo Sphere Viewer metadata cache.
|
|
591
642
|
* It is useful when current picture or sequence has changed server-side after first load.
|
|
643
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
592
644
|
*/
|
|
593
645
|
clearPictureMetadataCache() {
|
|
594
646
|
const oldPicId = this.getPictureMetadata()?.id;
|
|
@@ -609,7 +661,7 @@ export default class Photo extends PSViewer {
|
|
|
609
661
|
|
|
610
662
|
/**
|
|
611
663
|
* Change the shown position in picture
|
|
612
|
-
*
|
|
664
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
613
665
|
* @param {number} x X position (in degrees)
|
|
614
666
|
* @param {number} y Y position (in degrees)
|
|
615
667
|
* @param {number} z Z position (0-100)
|
|
@@ -623,6 +675,7 @@ export default class Photo extends PSViewer {
|
|
|
623
675
|
/**
|
|
624
676
|
* Enable or disable higher contrast on picture
|
|
625
677
|
* @param {boolean} enable True to enable higher contrast
|
|
678
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
626
679
|
*/
|
|
627
680
|
setHigherContrast(enable) {
|
|
628
681
|
this.renderer.renderer.toneMapping = enable ? 3 : 0;
|
|
@@ -633,6 +686,7 @@ export default class Photo extends PSViewer {
|
|
|
633
686
|
/**
|
|
634
687
|
* Get the duration of stay on a picture during a sequence play.
|
|
635
688
|
* @returns {number} The duration (in milliseconds)
|
|
689
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
636
690
|
*/
|
|
637
691
|
getTransitionDuration() {
|
|
638
692
|
return this._transitionDuration;
|
|
@@ -640,7 +694,7 @@ export default class Photo extends PSViewer {
|
|
|
640
694
|
|
|
641
695
|
/**
|
|
642
696
|
* Changes the duration of stay on a picture during a sequence play.
|
|
643
|
-
*
|
|
697
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
644
698
|
* @param {number} value The new duration (in milliseconds, between 100 and 3000)
|
|
645
699
|
*/
|
|
646
700
|
setTransitionDuration(value) {
|
|
@@ -652,19 +706,17 @@ export default class Photo extends PSViewer {
|
|
|
652
706
|
|
|
653
707
|
/**
|
|
654
708
|
* Event for transition duration change
|
|
655
|
-
*
|
|
656
|
-
* @
|
|
657
|
-
* @memberof CoreView
|
|
658
|
-
* @type {object}
|
|
659
|
-
* @property {object} detail Event information
|
|
709
|
+
* @event Panoramax.components.ui.Photo#transition-duration-changed
|
|
710
|
+
* @type {CustomEvent}
|
|
660
711
|
* @property {string} detail.duration New duration (in milliseconds)
|
|
661
712
|
*/
|
|
662
|
-
const event = new CustomEvent("
|
|
663
|
-
this.
|
|
713
|
+
const event = new CustomEvent("transition-duration-changed", { detail: { value } });
|
|
714
|
+
this.dispatchEvent(event);
|
|
664
715
|
}
|
|
665
716
|
|
|
717
|
+
/** @private */
|
|
666
718
|
setPanorama(path, options) {
|
|
667
|
-
const onFailure = e => this.showErrorOverlay(e, this._parent
|
|
719
|
+
const onFailure = e => this.showErrorOverlay(e, this._parent?._t.pnx.error_pic, true);
|
|
668
720
|
try {
|
|
669
721
|
return super.setPanorama(path, options).catch(onFailure);
|
|
670
722
|
}
|
|
@@ -678,14 +730,15 @@ export default class Photo extends PSViewer {
|
|
|
678
730
|
* @param {object} e The initial error
|
|
679
731
|
* @param {str} label The main error label to display
|
|
680
732
|
* @param {boolean} dissmisable Is error dissmisable
|
|
733
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
681
734
|
*/
|
|
682
735
|
showErrorOverlay(e, label, dissmisable) {
|
|
683
|
-
if(this._parent.
|
|
684
|
-
this._parent.
|
|
736
|
+
if(this._parent?.loader.isVisible() || !this.overlay.isVisible()) {
|
|
737
|
+
this._parent?.loader.dismiss(
|
|
685
738
|
e,
|
|
686
739
|
label,
|
|
687
740
|
dissmisable ? () => {
|
|
688
|
-
this._parent.
|
|
741
|
+
this._parent?.loader.dismiss();
|
|
689
742
|
this.overlay.hide();
|
|
690
743
|
} : undefined
|
|
691
744
|
);
|
|
@@ -694,10 +747,169 @@ export default class Photo extends PSViewer {
|
|
|
694
747
|
console.error(e);
|
|
695
748
|
this.overlay.show({
|
|
696
749
|
image: `<img style="width: 200px" src="${LogoDead}" alt="" />`,
|
|
697
|
-
title: this._parent
|
|
698
|
-
text: label + "<br />" + this._parent
|
|
750
|
+
title: this._parent?._t.pnx.error,
|
|
751
|
+
text: label + "<br />" + this._parent?._t.pnx.error_click,
|
|
699
752
|
dissmisable,
|
|
700
753
|
});
|
|
701
754
|
}
|
|
702
755
|
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Goes continuously to next picture in sequence as long as possible
|
|
759
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
760
|
+
*/
|
|
761
|
+
playSequence() {
|
|
762
|
+
this._sequencePlaying = true;
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Event for sequence starting to play
|
|
766
|
+
* @event Panoramax.components.ui.Photo#sequence-playing
|
|
767
|
+
* @type {CustomEvent}
|
|
768
|
+
*/
|
|
769
|
+
const event = new Event("sequence-playing", {bubbles: true, composed: true});
|
|
770
|
+
this.dispatchEvent(event);
|
|
771
|
+
|
|
772
|
+
const nextPicturePlay = () => {
|
|
773
|
+
if(this._sequencePlaying) {
|
|
774
|
+
this.addEventListener("picture-loaded", () => {
|
|
775
|
+
this._playTimer = setTimeout(() => {
|
|
776
|
+
nextPicturePlay();
|
|
777
|
+
}, this.getTransitionDuration());
|
|
778
|
+
}, { once: true });
|
|
779
|
+
|
|
780
|
+
try {
|
|
781
|
+
this.goToNextPicture();
|
|
782
|
+
}
|
|
783
|
+
catch(e) {
|
|
784
|
+
this.stopSequence();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
// Stop playing if user clicks on image
|
|
790
|
+
this.addEventListener("click", () => this.stopSequence());
|
|
791
|
+
|
|
792
|
+
nextPicturePlay();
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Stops playing current sequence
|
|
797
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
798
|
+
*/
|
|
799
|
+
stopSequence() {
|
|
800
|
+
this._sequencePlaying = false;
|
|
801
|
+
|
|
802
|
+
// Next picture timer is pending
|
|
803
|
+
if(this._playTimer) {
|
|
804
|
+
clearTimeout(this._playTimer);
|
|
805
|
+
delete this._playTimer;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// Force refresh of PSV to eventually load tiles
|
|
809
|
+
this.forceRefresh();
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Event for sequence stopped playing
|
|
813
|
+
* @event Panoramax.components.ui.Photo#sequence-stopped
|
|
814
|
+
* @type {CustomEvent}
|
|
815
|
+
*/
|
|
816
|
+
const event = new Event("sequence-stopped", {bubbles: true, composed: true});
|
|
817
|
+
this.dispatchEvent(event);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Is there any sequence being played right now ?
|
|
822
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
823
|
+
* @returns {boolean} True if sequence is playing
|
|
824
|
+
*/
|
|
825
|
+
isSequencePlaying() {
|
|
826
|
+
return this._sequencePlaying;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Starts/stops the reading of pictures in a sequence
|
|
831
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
832
|
+
*/
|
|
833
|
+
toggleSequencePlaying() {
|
|
834
|
+
if(this.isSequencePlaying()) {
|
|
835
|
+
this.stopSequence();
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
this.playSequence();
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Get current pictures navigation mode.
|
|
844
|
+
* @returns {string} The picture navigation mode ("any": no restriction, "seq": only pictures in same sequence, "pic": only selected picture)
|
|
845
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
846
|
+
*/
|
|
847
|
+
getPicturesNavigation() {
|
|
848
|
+
return this._picturesNavigation;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Switch the allowed navigation between pictures.
|
|
853
|
+
* @param {string} pn The picture navigation mode ("any": no restriction, "seq": only pictures in same sequence, "pic": only selected picture)
|
|
854
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
855
|
+
*/
|
|
856
|
+
setPicturesNavigation(pn) {
|
|
857
|
+
if(pn === "none") { pn = "pic"; }
|
|
858
|
+
this._picturesNavigation = pn;
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Event for pictures navigation mode change
|
|
862
|
+
* @event Panoramax.components.ui.Photo#pictures-navigation-changed
|
|
863
|
+
* @type {CustomEvent}
|
|
864
|
+
* @property {string} detail.value New mode (any, pic, seq)
|
|
865
|
+
*/
|
|
866
|
+
const event = new CustomEvent("pictures-navigation-changed", { detail: { value: pn } });
|
|
867
|
+
this.dispatchEvent(event);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Filter function
|
|
872
|
+
* @param {object} link A STAC next/prev/related link definition
|
|
873
|
+
* @returns {boolean} True if link should be kept
|
|
874
|
+
* @private
|
|
875
|
+
*/
|
|
876
|
+
_picturesNavFilter(link) {
|
|
877
|
+
switch(this._picturesNavigation) {
|
|
878
|
+
case "seq":
|
|
879
|
+
return ["next", "prev"].includes(link.rel);
|
|
880
|
+
case "pic":
|
|
881
|
+
case "none":
|
|
882
|
+
return false;
|
|
883
|
+
case "any":
|
|
884
|
+
default:
|
|
885
|
+
return true;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Force reload of texture and tiles.
|
|
891
|
+
* @memberof Panoramax.components.ui.Photo#
|
|
892
|
+
*/
|
|
893
|
+
forceRefresh() {
|
|
894
|
+
const cn = this._myVTour.getCurrentNode();
|
|
895
|
+
|
|
896
|
+
// Refresh mode for flat pictures
|
|
897
|
+
if(cn && cn.panorama.baseUrl !== cn?.panorama?.origBaseUrl) {
|
|
898
|
+
const prevZoom = this.getZoomLevel();
|
|
899
|
+
const prevPos = this.getPosition();
|
|
900
|
+
this._myVTour.state.currentNode = null;
|
|
901
|
+
this._myVTour.setCurrentNode(cn.id, {
|
|
902
|
+
zoomTo: prevZoom,
|
|
903
|
+
rotateTo: prevPos,
|
|
904
|
+
fadeIn: false,
|
|
905
|
+
speed: 0,
|
|
906
|
+
rotation: false,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// Refresh mode for 360 pictures
|
|
911
|
+
if(cn && cn.panorama.rows > 1) {
|
|
912
|
+
this.adapter.__refresh();
|
|
913
|
+
}
|
|
914
|
+
}
|
|
703
915
|
}
|