From 39c7e76ed5db06634f091fcd302bc591fbc70972 Mon Sep 17 00:00:00 2001 From: Damien Sorel Date: Mon, 19 Sep 2022 13:46:13 +0200 Subject: [PATCH 01/14] remove deprecated stuff --- docs/plugins/README.md | 2 +- docs/plugins/plugin-virtual-tour.md | 12 -- example/plugin-virtual-tour.html | 4 +- src/Viewer.js | 4 +- src/data/config.js | 5 +- src/index.js | 5 - src/plugins/markers/Marker.js | 10 +- src/plugins/markers/index.js | 7 +- .../virtual-tour/AbstractDatasource.js | 9 -- .../virtual-tour/ClientSideDatasource.js | 15 +-- src/plugins/virtual-tour/NodesListButton.js | 73 ------------ .../virtual-tour/ServerSideDatasource.js | 42 ++----- src/plugins/virtual-tour/constants.js | 41 ------- src/plugins/virtual-tour/index.js | 109 +++--------------- src/plugins/virtual-tour/nodes-list.svg | 1 - src/plugins/virtual-tour/utils.js | 3 + src/services/Renderer.js | 5 +- src/services/TextureLoader.js | 13 --- tests/types/index.ts | 4 +- types/index.d.ts | 4 - types/plugins/markers/index.d.ts | 4 +- types/plugins/virtual-tour/index.d.ts | 24 ---- 22 files changed, 46 insertions(+), 350 deletions(-) delete mode 100644 src/plugins/virtual-tour/NodesListButton.js delete mode 100644 src/plugins/virtual-tour/nodes-list.svg diff --git a/docs/plugins/README.md b/docs/plugins/README.md index 879301a44..c3558bd8f 100644 --- a/docs/plugins/README.md +++ b/docs/plugins/README.md @@ -47,7 +47,7 @@ const viewer = new PhotoSphereViewer.Viewer({ }); ``` -After initializayion the plugin instance can be obtained with the `getPlugin` method, allowing to call methods on the plugin and subscribe to events. +After initialization the plugin instance can be obtained with the `getPlugin` method, allowing to call methods on the plugin and subscribe to events. ```js const markersPlugin = viewer.getPlugin(PhotoSphereViewer.MarkersPlugin); diff --git a/docs/plugins/plugin-virtual-tour.md b/docs/plugins/plugin-virtual-tour.md index e58ea8be4..9f3f8ac5b 100644 --- a/docs/plugins/plugin-virtual-tour.md +++ b/docs/plugins/plugin-virtual-tour.md @@ -465,15 +465,3 @@ virtualTourPlugin.on('node-changed', (e, nodeId, data) => { } }); ``` - - -## Buttons - -This plugin adds buttons to the default navbar: -- `nodesList` allows to open a list of all nodes on the left panel (client mode only) - -If you use a [custom navbar](../guide/navbar.md) you will need to manually add the buttons to the list. - -::: warning Deprecated -This button will be removed and replaced by the [Gallery plugin](./plugin-gallery.md). -::: diff --git a/example/plugin-virtual-tour.html b/example/plugin-virtual-tour.html index d6d84f015..70e005f77 100644 --- a/example/plugin-virtual-tour.html +++ b/example/plugin-virtual-tour.html @@ -150,11 +150,11 @@ arrowPosition: 'bottom', // client mode - dataMode: PhotoSphereViewer.VirtualTourPlugin.MODE_CLIENT, + // dataMode: PhotoSphereViewer.VirtualTourPlugin.MODE_CLIENT, nodes : nodes, // server mode (mock) - // dataMode: PhotoSphereViewer.VirtualTourPlugin.MODE_SERVER, + dataMode: PhotoSphereViewer.VirtualTourPlugin.MODE_SERVER, getNode: (nodeId) => { console.log('GET node ' + nodeId); return Promise.resolve({ diff --git a/src/Viewer.js b/src/Viewer.js index a3f23c5ce..27eb0e279 100644 --- a/src/Viewer.js +++ b/src/Viewer.js @@ -77,7 +77,7 @@ export class Viewer extends EventEmitter { * @property {number} hFov - horizontal FOV * @property {number} aspect - viewer aspect ratio * @property {boolean} autorotateEnabled - automatic rotation is enabled - * @property {PSV.Animation} animationPromise - promise of the current animation + * @property {PSV.utils.Animation} animationPromise - promise of the current animation * @property {Promise} loadingPromise - promise of the setPanorama method * @property {boolean} littlePlanet - special tweaks for LittlePlanetAdapter * @property {number} idleTime - time of the last user action @@ -826,7 +826,7 @@ export class Viewer extends EventEmitter { /** * @summary Rotates and zooms the view with a smooth animation * @param {PSV.AnimateOptions} options - position and/or zoom level - * @returns {PSV.Animation} + * @returns {PSV.utils.Animation} */ animate(options) { this.__stopAll(); diff --git a/src/data/config.js b/src/data/config.js index b410ece33..24e407bee 100644 --- a/src/data/config.js +++ b/src/data/config.js @@ -101,10 +101,7 @@ export const READONLY_OPTIONS = { * @private */ export const DEPRECATED_OPTIONS = { - zoomButtonIncrement : 'zoomButtonIncrement is deprecated, use zoomSpeed', - mousewheelSpeed : 'mousewheelSpeed is deprecated, use zoomSpeed', - sphereCorrectionReorder: 'sphereCorrectionReorder is deprecated', - captureCursor : 'captureCursor is deprecated', + captureCursor: 'captureCursor is deprecated', }; /** diff --git a/src/index.js b/src/index.js index fd001fb84..b52283e65 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,6 @@ import { SYSTEM } from './data/system'; import { AbstractPlugin } from './plugins/AbstractPlugin'; import { PSVError } from './PSVError'; import * as utils from './utils'; -import { Animation } from './utils/Animation'; import { Viewer } from './Viewer'; import './styles/index.scss'; @@ -19,10 +18,6 @@ export { AbstractButton, AbstractComponent, AbstractPlugin, - /** - * @deprecated use `utils.Animation` - */ - Animation, CONSTANTS, DEFAULTS, EquirectangularAdapter, diff --git a/src/plugins/markers/Marker.js b/src/plugins/markers/Marker.js index 80685052b..180cd931c 100644 --- a/src/plugins/markers/Marker.js +++ b/src/plugins/markers/Marker.js @@ -422,14 +422,8 @@ export class Marker { this.props.anchor = utils.parsePosition(this.config.anchor); // clean scale - if (this.config.scale) { - if (typeof this.config.scale === 'number') { - utils.logWarn('Single value marker scale is deprecated, please use an array of two values.'); - this.config.scale = { zoom: [0, this.config.scale] }; - } - if (Array.isArray(this.config.scale)) { - this.config.scale = { zoom: this.config.scale }; - } + if (this.config.scale && Array.isArray(this.config.scale)) { + this.config.scale = { zoom: this.config.scale }; } if (this.isNormal()) { diff --git a/src/plugins/markers/index.js b/src/plugins/markers/index.js index bc7191093..d3d4e8391 100644 --- a/src/plugins/markers/index.js +++ b/src/plugins/markers/index.js @@ -85,11 +85,6 @@ export class MarkersPlugin extends AbstractPlugin { ...options, }; - if (options?.listButton === false || options?.hideButton === false) { - utils.logWarn('MarkersPlugin: listButton and hideButton options are deprecated. ' - + 'Please define the global navbar options according to your needs.'); - } - /** * @member {HTMLElement} * @readonly @@ -441,7 +436,7 @@ export class MarkersPlugin extends AbstractPlugin { * @param {string} markerId * @param {string|number} [speed] - rotates smoothy, see {@link PSV.Viewer#animate} * @fires PSV.plugins.MarkersPlugin.goto-marker-done - * @return {PSV.Animation} A promise that will be resolved when the animation finishes + * @return {PSV.utils.Animation} A promise that will be resolved when the animation finishes */ gotoMarker(markerId, speed) { const marker = this.getMarker(markerId); diff --git a/src/plugins/virtual-tour/AbstractDatasource.js b/src/plugins/virtual-tour/AbstractDatasource.js index 8c6f216b7..fb024079a 100644 --- a/src/plugins/virtual-tour/AbstractDatasource.js +++ b/src/plugins/virtual-tour/AbstractDatasource.js @@ -31,13 +31,4 @@ export class AbstractDatasource { throw new PSVError('loadNode not implemented'); } - /** - * @summary Loades nodes linked to another node - * @param {string} nodeId - * @return {Promise} - */ - loadLinkedNodes(nodeId) { // eslint-disable-line no-unused-vars - throw new PSVError('loadLinkedNodes not implemented'); - } - } diff --git a/src/plugins/virtual-tour/ClientSideDatasource.js b/src/plugins/virtual-tour/ClientSideDatasource.js index 75553804a..006e97a33 100644 --- a/src/plugins/virtual-tour/ClientSideDatasource.js +++ b/src/plugins/virtual-tour/ClientSideDatasource.js @@ -17,15 +17,6 @@ export class ClientSideDatasource extends AbstractDatasource { } } - loadLinkedNodes(nodeId) { - if (!this.nodes[nodeId]) { - return Promise.reject(new PSVError(`Node ${nodeId} not found`)); - } - else { - return Promise.resolve(); - } - } - setNodes(rawNodes) { if (!rawNodes?.length) { throw new PSVError('No nodes provided'); @@ -42,7 +33,7 @@ export class ClientSideDatasource extends AbstractDatasource { } if (!node.links) { utils.logWarn(`Node ${node.id} has no links`); - nodes.links = []; + node.links = []; } nodes[node.id] = node; @@ -50,8 +41,6 @@ export class ClientSideDatasource extends AbstractDatasource { rawNodes.forEach((node) => { node.links.forEach((link) => { - checkLink(node, link, this.plugin.isGps()); - if (!nodes[link.nodeId]) { throw new PSVError(`Target node ${link.nodeId} of node ${node.id} does not exists`); } @@ -60,6 +49,8 @@ export class ClientSideDatasource extends AbstractDatasource { link.position = link.position || nodes[link.nodeId].position; link.name = link.name || nodes[link.nodeId].name; + checkLink(node, link, this.plugin.isGps()); + linkedNodes[link.nodeId] = true; }); }); diff --git a/src/plugins/virtual-tour/NodesListButton.js b/src/plugins/virtual-tour/NodesListButton.js deleted file mode 100644 index 02127a102..000000000 --- a/src/plugins/virtual-tour/NodesListButton.js +++ /dev/null @@ -1,73 +0,0 @@ -import { AbstractButton, CONSTANTS } from '../..'; -import { ID_PANEL_NODES_LIST } from './constants'; -import nodesList from './nodes-list.svg'; - -/** - * @summary Navigation bar markers list button class - * @extends PSV.buttons.AbstractButton - * @memberof PSV.buttons - */ -export class NodesListButton extends AbstractButton { - - static id = 'nodesList'; - static icon = nodesList; - - /** - * @param {PSV.components.Navbar} navbar - */ - constructor(navbar) { - super(navbar, 'psv-button--hover-scale psv-nodes-list-button', true); - - /** - * @type {PSV.plugins.VirtualTourPlugin} - */ - this.plugin = this.psv.getPlugin('virtual-tour'); - - if (this.plugin) { - this.psv.on(CONSTANTS.EVENTS.OPEN_PANEL, this); - this.psv.on(CONSTANTS.EVENTS.CLOSE_PANEL, this); - } - } - - /** - * @override - */ - destroy() { - this.psv.off(CONSTANTS.EVENTS.OPEN_PANEL, this); - this.psv.off(CONSTANTS.EVENTS.CLOSE_PANEL, this); - - super.destroy(); - } - - /** - * @override - */ - isSupported() { - return !!this.plugin && !this.plugin.isServerSide() && !this.plugin.gallery; - } - - /** - * @summary Handles events - * @param {Event} e - * @private - */ - handleEvent(e) { - /* eslint-disable */ - switch (e.type) { - // @formatter:off - case CONSTANTS.EVENTS.OPEN_PANEL: this.toggleActive(e.args[0] === ID_PANEL_NODES_LIST); break; - case CONSTANTS.EVENTS.CLOSE_PANEL: this.toggleActive(false); break; - // @formatter:on - } - /* eslint-enable */ - } - - /** - * @override - * @description Toggles nodes list - */ - onClick() { - this.plugin.toggleNodesList(); - } - -} diff --git a/src/plugins/virtual-tour/ServerSideDatasource.js b/src/plugins/virtual-tour/ServerSideDatasource.js index bcc61b425..518fce5ca 100644 --- a/src/plugins/virtual-tour/ServerSideDatasource.js +++ b/src/plugins/virtual-tour/ServerSideDatasource.js @@ -16,7 +16,6 @@ export class ServerSideDatasource extends AbstractDatasource { } this.nodeResolver = plugin.config.getNode; - this.linksResolver = plugin.config.getLinks; } loadNode(nodeId) { @@ -27,48 +26,23 @@ export class ServerSideDatasource extends AbstractDatasource { return Promise.resolve(this.nodeResolver(nodeId)) .then((node) => { checkNode(node, this.plugin.isGps()); - this.nodes[nodeId] = node; - return node; - }); - } - } - - loadLinkedNodes(nodeId) { - if (!this.nodes[nodeId]) { - return Promise.reject(new PSVError(`Node ${nodeId} not found`)); - } - else if (this.nodes[nodeId].links) { - return Promise.resolve(); - } - else { - if (!this.linksResolver) { - this.nodes[nodeId].links = []; - return Promise.resolve(); - } - - utils.logWarn(`getLinks() option is deprecated, instead make getNode() also return the node' links.`); - - return Promise.resolve(this.linksResolver(nodeId)) - .then(links => links || []) - .then((links) => { - const node = this.nodes[nodeId]; - - links.forEach((link) => { - checkLink(node, link, this.plugin.isGps()); + if (!node.links) { + utils.logWarn(`Node ${node.id} has no links`); + node.links = []; + } + node.links.forEach((link) => { // copy essential data if (this.nodes[link.nodeId]) { link.position = link.position || this.nodes[link.nodeId].position; link.name = link.name || this.nodes[link.nodeId].name; } - if (this.plugin.isGps() && !link.position) { - throw new PSVError(`No GPS position provided for link ${link.nodeId} of node ${node.id}`); - } + checkLink(node, link, this.plugin.isGps()); }); - // store links - node.links = links; + this.nodes[nodeId] = node; + return node; }); } } diff --git a/src/plugins/virtual-tour/constants.js b/src/plugins/virtual-tour/constants.js index 493608fa2..2ca737050 100644 --- a/src/plugins/virtual-tour/constants.js +++ b/src/plugins/virtual-tour/constants.js @@ -2,7 +2,6 @@ import { ObjectLoader } from 'three'; import arrowGeometryJson from './arrow.json'; import arrowIconSvg from './arrow.svg'; import arrowOutlineGeometryJson from './arrow_outline.json'; -import nodesList from './nodes-list.svg'; /** * @summary In client mode all the nodes are provided in the config or with the `setNodes` method @@ -66,14 +65,6 @@ export const EVENTS = { * @param {string} nodeId */ NODE_CHANGED : 'node-changed', - /** - * @event filter:render-nodes-list - * @memberof PSV.plugins.VirtualTourPlugin - * @summary Used to alter the list of nodes displayed on the side-panel - * @param {PSV.plugins.VirtualTourPlugin.Node[]} nodes - * @returns {PSV.plugins.VirtualTourPlugin.Node[]} - */ - RENDER_NODES_LIST: 'render-nodes-list', }; /** @@ -133,35 +124,3 @@ export const { ARROW_GEOM, ARROW_OUTLINE_GEOM } = (() => { arrowOutline.rotateX(rot); return { ARROW_GEOM: arrow, ARROW_OUTLINE_GEOM: arrowOutline }; })(); - -/** - * @summary Panel identifier for nodes list - * @type {string} - * @constant - * @private - */ -export const ID_PANEL_NODES_LIST = 'virtualTourNodesList'; - -/** - * @summary Nodes list template - * @param {PSV.plugins.VirtualTourPlugin.Node[]} nodes - * @param {string} title - * @param {string} currentNodeId - * @returns {string} - * @constant - * @private - */ -export const NODES_LIST_TEMPLATE = (nodes, title, currentNodeId) => ` -
-

${nodesList} ${title}

-
    - ${nodes.map(node => ` -
  • - ${node.thumbnail ? `` : ''} - ${node.caption || node.name} -
  • - `).join('')} -
-
-`; diff --git a/src/plugins/virtual-tour/index.js b/src/plugins/virtual-tour/index.js index 6afb43633..48ad9013d 100644 --- a/src/plugins/virtual-tour/index.js +++ b/src/plugins/virtual-tour/index.js @@ -8,7 +8,7 @@ import { MeshLambertMaterial, PointLight } from 'three'; -import { AbstractPlugin, CONSTANTS, DEFAULTS, PSVError, registerButton, utils } from '../..'; +import { AbstractPlugin, CONSTANTS, PSVError, utils } from '../..'; import { ClientSideDatasource } from './ClientSideDatasource'; import { ARROW_GEOM, @@ -16,17 +16,14 @@ import { DEFAULT_ARROW, DEFAULT_MARKER, EVENTS, - ID_PANEL_NODES_LIST, LINK_DATA, MODE_3D, MODE_CLIENT, MODE_GPS, MODE_MANUAL, MODE_MARKERS, - MODE_SERVER, - NODES_LIST_TEMPLATE + MODE_SERVER } from './constants'; -import { NodesListButton } from './NodesListButton'; import { ServerSideDatasource } from './ServerSideDatasource'; import './style.scss'; import { bearing, distance, setMeshColor } from './utils'; @@ -40,15 +37,6 @@ import { bearing, distance, setMeshColor } from './utils'; * @returns {PSV.plugins.VirtualTourPlugin.Node|Promise} */ -/** - * @callback GetLinks - * @summary Function to load the links of a node - * @deprecated `getNode` must directly return the links of each node - * @memberOf PSV.plugins.VirtualTourPlugin - * @param {string} nodeId - * @returns {PSV.plugins.VirtualTourPlugin.NodeLink[]|Promise} - */ - /** * @callback Preload * @summary Function to determine if a link must be preloaded @@ -70,7 +58,7 @@ import { bearing, distance, setMeshColor } from './utils'; * @property {string} [name] - short name of the node * @property {string} [caption] - caption visible in the navbar * @property {string} [description] - description visible in the side panel - * @property {string} [thumbnail] - thumbnail for the nodes list in the side panel + * @property {string} [thumbnail] - thumbnail for the gallery * @property {PSV.plugins.MarkersPlugin.Properties[]} [markers] - additional markers to use on this node */ @@ -100,7 +88,6 @@ import { bearing, distance, setMeshColor } from './utils'; * @property {'markers'|'3d'} [renderMode='3d'] - configure rendering mode of links * @property {PSV.plugins.VirtualTourPlugin.Node[]} [nodes] - initial nodes * @property {PSV.plugins.VirtualTourPlugin.GetNode} [getNode] - * @property {PSV.plugins.VirtualTourPlugin.GetLinks} [getLinks] - Deprecated: `getNode` must directly return the links of each node * @property {string} [startNodeId] - id of the initial node, if not defined the first node will be used * @property {boolean|PSV.plugins.VirtualTourPlugin.Preload} [preload=false] - preload linked panoramas * @property {boolean|string|number} [rotateSpeed='20rpm'] - speed of rotation when clicking on a link, if 'false' the viewer won't rotate at all @@ -120,10 +107,6 @@ import { bearing, distance, setMeshColor } from './utils'; * @type {PSV.Position} [fromLinkPosition] - The position of the link on the previous node */ -// add markers buttons -DEFAULTS.lang[NodesListButton.id] = 'Locations'; -registerButton(NodesListButton, 'caption:left'); - export { EVENTS, MODE_3D, MODE_CLIENT, MODE_GPS, MODE_MANUAL, MODE_MARKERS, MODE_SERVER } from './constants'; @@ -188,24 +171,16 @@ export class VirtualTourPlugin extends AbstractPlugin { arrowPosition : 'bottom', linksOnCompass : options?.renderMode === MODE_MARKERS, ...options, - markerStyle : { + markerStyle: { ...DEFAULT_MARKER, ...options?.markerStyle, }, - arrowStyle : { + arrowStyle : { ...DEFAULT_ARROW, ...options?.arrowStyle, }, }; - if (options?.listButton === false) { - utils.logWarn('VirtualTourPlugin: listButton option is deprecated. ' - + 'Please define the global navbar options according to your needs.'); - } - if (options?.listButton === true && this.config.dataMode === MODE_SERVER) { - utils.logWarn('VirtualTourPlugin: the list button is not supported in server mode.'); - } - /** * @type {PSV.plugins.MarkersPlugin} * @private @@ -489,21 +464,18 @@ export class VirtualTourPlugin extends AbstractPlugin { this.markers?.clearMarkers(); this.compass?.clearHotspots(); - return Promise.all([ - this.psv.setPanorama(node.panorama, { - transition : this.config.transition, - caption : node.caption, - description : node.description, - panoData : node.panoData, - sphereCorrection: node.sphereCorrection, - }) - .then((completed) => { - if (!completed) { - throw utils.getAbortError(); - } - }), - this.datasource.loadLinkedNodes(nodeId), - ]); + return this.psv.setPanorama(node.panorama, { + transition : this.config.transition, + caption : node.caption, + description : node.description, + panoData : node.panoData, + sphereCorrection: node.sphereCorrection, + }) + .then((completed) => { + if (!completed) { + throw utils.getAbortError(); + } + }); }) .then(() => { if (this.prop.loadingNode !== nodeId) { @@ -745,51 +717,4 @@ export class VirtualTourPlugin extends AbstractPlugin { }); } - /** - * @summary Toggles the visibility of the list of nodes - */ - toggleNodesList() { - if (this.psv.panel.prop.contentId === ID_PANEL_NODES_LIST) { - this.hideNodesList(); - } - else { - this.showNodesList(); - } - } - - /** - * @summary Opens side panel with the list of nodes - */ - showNodesList() { - utils.logWarn(`Starting from next version, the VirtualTourPlugin will require the GalleryPlugin to display the list of nodes.`); - - const nodes = this.change(EVENTS.RENDER_NODES_LIST, Object.values(this.datasource.nodes)); - - this.psv.panel.show({ - id : ID_PANEL_NODES_LIST, - content : NODES_LIST_TEMPLATE( - nodes, - this.psv.config.lang[NodesListButton.id], - this.prop.currentNode?.id - ), - noMargin : true, - clickHandler: (e) => { - const li = e.target ? utils.getClosest(e.target, 'li') : undefined; - const nodeId = li ? li.dataset.nodeId : undefined; - - if (nodeId) { - this.setCurrentNode(nodeId); - this.hideNodesList(); - } - }, - }); - } - - /** - * @summary Closes side panel if it contains the list of nodes - */ - hideNodesList() { - this.psv.panel.hide(ID_PANEL_NODES_LIST); - } - } diff --git a/src/plugins/virtual-tour/nodes-list.svg b/src/plugins/virtual-tour/nodes-list.svg deleted file mode 100644 index 0cd9fed65..000000000 --- a/src/plugins/virtual-tour/nodes-list.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/plugins/virtual-tour/utils.js b/src/plugins/virtual-tour/utils.js index 0aa83aa87..afa212ba2 100644 --- a/src/plugins/virtual-tour/utils.js +++ b/src/plugins/virtual-tour/utils.js @@ -32,6 +32,9 @@ export function checkLink(node, link, isGps) { if (!isGps && !utils.isExtendedPosition(link)) { throw new PSVError(`No position provided for link ${link.nodeId} of node ${node.id}`); } + if (isGps && !link.position) { + throw new PSVError(`No GPS position provided for link ${link.nodeId} of node ${node.id}`); + } } /** diff --git a/src/services/Renderer.js b/src/services/Renderer.js index 1e7301a6e..57bf81de0 100644 --- a/src/services/Renderer.js +++ b/src/services/Renderer.js @@ -1,8 +1,7 @@ import { Group, PerspectiveCamera, Raycaster, Scene, Vector3, WebGLRenderer } from 'three'; import { EVENTS, MESH_USER_DATA, SPHERE_RADIUS } from '../data/constants'; import { SYSTEM } from '../data/system'; -import { each, isExtendedPosition } from '../utils'; -import { Animation } from '../utils/Animation'; +import { Animation, each, isExtendedPosition } from '../utils'; import { AbstractService } from './AbstractService'; /** @@ -300,7 +299,7 @@ export class Renderer extends AbstractService { * @summary Performs transition between the current and a new texture * @param {PSV.TextureData} textureData * @param {PSV.PanoramaOptions} options - * @returns {PSV.Animation} + * @returns {PSV.utils.Animation} * @package */ transition(textureData, options) { diff --git a/src/services/TextureLoader.js b/src/services/TextureLoader.js index c2d178251..956e1579b 100644 --- a/src/services/TextureLoader.js +++ b/src/services/TextureLoader.js @@ -37,19 +37,6 @@ export class TextureLoader extends AbstractService { super.destroy(); } - /** - * @summary Loads the panorama texture(s) - * @param {*} panorama - * @param {PSV.PanoData | PSV.PanoDataProvider} [newPanoData] - * @returns {Promise.} - * @throws {PSV.PSVError} when the image cannot be loaded - * @package - * @deprecated - */ - loadTexture(panorama, newPanoData) { - return this.psv.adapter.loadTexture(panorama, newPanoData); - } - /** * @summary Cancels current HTTP requests * @package diff --git a/tests/types/index.ts b/tests/types/index.ts index a619031e2..cbca044b9 100644 --- a/tests/types/index.ts +++ b/tests/types/index.ts @@ -1,4 +1,4 @@ -import { Animation, CONSTANTS, Viewer } from 'photo-sphere-viewer'; +import { CONSTANTS, utils, Viewer } from 'photo-sphere-viewer'; import { EquirectangularTilesAdapter, EquirectangularTilesPanorama @@ -82,7 +82,7 @@ customPlugin.doSomething(); const customPluginAgain = viewer.getPlugin('custom'); customPluginAgain.doSomething(); -const anim = new Animation({ +const anim = new utils.Animation({ duration: 1000, properties: { foo: {start: 0, end: 1}, diff --git a/types/index.d.ts b/types/index.d.ts index 6e89b299d..fc22a5b35 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -19,9 +19,5 @@ export * from './PSVError'; export * from './services/DataHelper'; export * from './services/TextureLoader'; export * from './services/TooltipRenderer'; -/** - * @deprecated use `utils.Animation` - */ -export * from './utils/Animation'; export * from './Viewer'; export { CONSTANTS, utils }; diff --git a/types/plugins/markers/index.d.ts b/types/plugins/markers/index.d.ts index dc8f21425..779850a89 100644 --- a/types/plugins/markers/index.d.ts +++ b/types/plugins/markers/index.d.ts @@ -1,4 +1,4 @@ -import { AbstractPlugin, Animation, ExtendedPosition, Viewer } from '../..'; +import { AbstractPlugin, ExtendedPosition, utils, Viewer } from '../..'; import { Event } from 'uevent'; export type MarkerType = @@ -212,7 +212,7 @@ export class MarkersPlugin extends AbstractPlugin { /** * @summary Rotate the view to face the marker */ - gotoMarker(markerId: string, speed: string | number): Animation; + gotoMarker(markerId: string, speed: string | number): utils.Animation; /** * @summary Hides a marker diff --git a/types/plugins/virtual-tour/index.d.ts b/types/plugins/virtual-tour/index.d.ts index c2a1b597d..c761ca48f 100644 --- a/types/plugins/virtual-tour/index.d.ts +++ b/types/plugins/virtual-tour/index.d.ts @@ -36,10 +36,6 @@ export type VirtualTourArrowStyle = { color?: string; hoverColor?: string; outlineColor?: number; - /** - * @deprecated - */ - opacity?: number; scale?: [number, number]; }; @@ -63,10 +59,6 @@ export type VirtualTourPluginOptions = { renderMode?: '3d' | 'markers'; nodes?: VirtualTourNode[]; getNode?: (nodeId: string) => VirtualTourNode | Promise; - /** - * @deprecated - */ - getLinks?: (nodeId: string) => VirtualTourNodeLink[] | Promise; startNodeId?: string; preload?: boolean | ((node: VirtualTourNode, link: VirtualTourNodeLink) => boolean); rotateSpeed?: boolean | string | number; @@ -84,7 +76,6 @@ export type VirtualTourPluginPluginOptions = VirtualTourPluginOptions; export const EVENTS: { NODE_CHANGED: 'node-changed', - RENDER_NODES_LIST: 'render-nodes-list', }; export const MODE_CLIENT = 'client'; @@ -120,21 +111,6 @@ export class VirtualTourPlugin extends AbstractPlugin { */ setCurrentNode(nodeId: string): Promise; - /** - * @summary Toggles the visibility of the list of nodes - */ - toggleNodesList(); - - /** - * @summary Opens side panel with the list of nodes - */ - showNodesList(); - - /** - * @summary Closes side panel if it contains the list of nodes - */ - hideNodesList(); - /** * @summary Triggered when the current node changes */ From 7f4afda954ff8fed5c93df32f738b69af061ca49 Mon Sep 17 00:00:00 2001 From: Damien Sorel Date: Tue, 20 Sep 2022 13:15:26 +0200 Subject: [PATCH 02/14] gallery: hide button if no items --- src/buttons/AbstractButton.js | 7 +------ src/components/AbstractComponent.js | 7 ++++--- src/components/NavbarCaption.js | 8 +------- src/plugins/gallery/GalleryButton.js | 4 ++++ src/plugins/gallery/index.js | 11 +++++++++-- src/plugins/markers/index.js | 12 ++++-------- types/components/AbstractComponent.d.ts | 2 +- 7 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/buttons/AbstractButton.js b/src/buttons/AbstractButton.js index cc319438c..ade0d2324 100644 --- a/src/buttons/AbstractButton.js +++ b/src/buttons/AbstractButton.js @@ -119,12 +119,7 @@ export class AbstractButton extends AbstractComponent { return; // the component has been destroyed } this.prop.supported = supported; - if (!supported) { - this.hide(); - } - else { - this.show(); - } + this.toggle(supported); }); } else { diff --git a/src/components/AbstractComponent.js b/src/components/AbstractComponent.js index 37c319052..b01605558 100644 --- a/src/components/AbstractComponent.js +++ b/src/components/AbstractComponent.js @@ -90,12 +90,13 @@ export class AbstractComponent { /** * @summary Displays or hides the component + * @param {boolean} [visible] - forced state */ - toggle() { - if (this.isVisible()) { + toggle(visible) { + if (visible === false || visible === undefined && this.isVisible()) { this.hide(); } - else { + else if (visible === true || visible === undefined && !this.isVisible()) { this.show(); } } diff --git a/src/components/NavbarCaption.js b/src/components/NavbarCaption.js index 28e34605f..c0ca5db77 100644 --- a/src/components/NavbarCaption.js +++ b/src/components/NavbarCaption.js @@ -69,13 +69,7 @@ export class NavbarCaption extends AbstractComponent { * @private */ refreshUi() { - const availableWidth = this.container.offsetWidth; - if (availableWidth >= this.prop.contentWidth) { - this.show(); - } - else if (availableWidth < this.prop.contentWidth) { - this.hide(); - } + this.toggle(this.container.offsetWidth >= this.prop.contentWidth); this.__refreshButton(); } diff --git a/src/plugins/gallery/GalleryButton.js b/src/plugins/gallery/GalleryButton.js index 20adcf7fd..b5d5630b7 100644 --- a/src/plugins/gallery/GalleryButton.js +++ b/src/plugins/gallery/GalleryButton.js @@ -29,6 +29,10 @@ export class GalleryButton extends AbstractButton { this.plugin.on(EVENTS.SHOW_GALLERY, this); this.plugin.on(EVENTS.HIDE_GALLERY, this); } + + if (!this.plugin?.items.length) { + this.hide(); + } } /** diff --git a/src/plugins/gallery/index.js b/src/plugins/gallery/index.js index c231df7a2..f47f8fa2a 100644 --- a/src/plugins/gallery/index.js +++ b/src/plugins/gallery/index.js @@ -152,7 +152,12 @@ export class GalleryPlugin extends AbstractPlugin { * @summary Hides or shows the gallery */ toggle() { - return this.gallery.toggle(); + if (this.gallery.isVisible()) { + this.hide(); + } + else { + this.show(); + } } /** @@ -181,7 +186,9 @@ export class GalleryPlugin extends AbstractPlugin { id: `${item.id}`, })); - this.gallery.setItems(items); + this.gallery.setItems(this.items); + + this.psv.navbar.getButton(GalleryButton.id, false)?.toggle(this.items.length > 0); } /** diff --git a/src/plugins/markers/index.js b/src/plugins/markers/index.js index d3d4e8391..ff17d9c96 100644 --- a/src/plugins/markers/index.js +++ b/src/plugins/markers/index.js @@ -972,13 +972,8 @@ export class MarkersPlugin extends AbstractPlugin { */ __refreshUi() { const nbMarkers = Object.values(this.markers).filter(m => !m.config.hideList).length; - const markersButton = this.psv.navbar.getButton(MarkersButton.id, false); - const markersListButton = this.psv.navbar.getButton(MarkersListButton.id, false); if (nbMarkers === 0) { - markersButton?.hide(); - markersListButton?.hide(); - if (this.psv.panel.isVisible(ID_PANEL_MARKERS_LIST)) { this.psv.panel.hide(); } @@ -987,9 +982,7 @@ export class MarkersPlugin extends AbstractPlugin { } } else { - markersButton?.show(); - markersListButton?.show(); - + // eslint-disable-next-line no-lonely-if if (this.psv.panel.isVisible(ID_PANEL_MARKERS_LIST)) { this.showMarkersList(); } @@ -997,6 +990,9 @@ export class MarkersPlugin extends AbstractPlugin { this.prop.currentMarker ? this.showMarkerPanel(this.prop.currentMarker) : this.psv.panel.hide(); } } + + this.psv.navbar.getButton(MarkersButton.id, false)?.toggle(nbMarkers > 0); + this.psv.navbar.getButton(MarkersListButton.id, false)?.toggle(nbMarkers > 0); } /** diff --git a/types/components/AbstractComponent.d.ts b/types/components/AbstractComponent.d.ts index 6c57b28b4..c277d3575 100644 --- a/types/components/AbstractComponent.d.ts +++ b/types/components/AbstractComponent.d.ts @@ -20,7 +20,7 @@ export abstract class AbstractComponent { /** * @summary Displays or hides the component */ - toggle(); + toggle(visible?: boolean); /** * @summary Check if the component is visible From 71748b629bbeadd7b7af177e8761b442245f22c8 Mon Sep 17 00:00:00 2001 From: Damien Sorel Date: Wed, 21 Sep 2022 13:12:08 +0200 Subject: [PATCH 03/14] doc: add autorotate to animation demo (#758) --- docs/demos/basic/6-animation.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/demos/basic/6-animation.md b/docs/demos/basic/6-animation.md index 61e4df585..fc835952f 100644 --- a/docs/demos/basic/6-animation.md +++ b/docs/demos/basic/6-animation.md @@ -41,6 +41,8 @@ const viewer = new PhotoSphereViewer.Viewer({ viewer.on('ready', intro); function intro() { + viewer.stopAutorotate(); + new PhotoSphereViewer.utils.Animation({ properties: animatedValues, duration: 2500, @@ -50,7 +52,15 @@ function intro() { viewer.rotate({ longitude: properties.longitude, latitude: properties.latitude }); viewer.zoom(properties.zoom); } - }); + }) + .then(() => { + viewer.setOptions({ + autorotateLat: animatedValues.latitude.end, + autorotateDelay: 1000, + autorotateIdle: true, + }); + viewer.startAutorotate(); + }); } ``` From 51c4f699a6c9d94f2e79a5f9068a4a797d496f5f Mon Sep 17 00:00:00 2001 From: mistic100 Date: Wed, 21 Sep 2022 22:10:11 +0200 Subject: [PATCH 04/14] allow more positions for tooltips "right top", "right bottom", "left top", "left bottom" --- docs/demos/markers/custom-tooltip.md | 1 + docs/plugins/plugin-markers.md | 6 +- example/components.html | 15 ++- example/plugin-markers.html | 4 +- src/components/Tooltip.js | 174 ++++++++++++++++----------- src/plugins/compass/index.js | 3 +- src/plugins/markers/Marker.js | 17 ++- src/services/TooltipRenderer.js | 8 +- src/styles/tooltip.scss | 91 +++++++------- src/utils/psv.js | 67 +++++++++-- src/utils/psv.spec.js | 32 +++-- types/plugins/markers/index.d.ts | 2 +- types/utils/psv.d.ts | 5 +- 13 files changed, 262 insertions(+), 163 deletions(-) diff --git a/docs/demos/markers/custom-tooltip.md b/docs/demos/markers/custom-tooltip.md index 54aab5126..f0c1f026d 100644 --- a/docs/demos/markers/custom-tooltip.md +++ b/docs/demos/markers/custom-tooltip.md @@ -28,6 +28,7 @@ const viewer = new PhotoSphereViewer.Viewer({ tooltip : { content : document.querySelector('#tooltip-content').innerText, className: 'custom-tooltip', + position : 'top', trigger : 'click', }, latitude : 0.11, diff --git a/docs/plugins/plugin-markers.md b/docs/plugins/plugin-markers.md index 27e1bfeb2..67859addc 100644 --- a/docs/plugins/plugin-markers.md +++ b/docs/plugins/plugin-markers.md @@ -133,7 +133,7 @@ const viewer = new PhotoSphereViewer.Viewer({ }, tooltip: { content: 'A dynamic polygon marker', - position: 'right bottom' + position: 'bottom right' } }, { @@ -427,7 +427,7 @@ Initial visibility of the marker. - type: `string | {content: string, position: string, className: string, trigger: string}` - default: `{content: null, position: 'top center', className: null, trigger: 'hover'}` -Accepted positions are combinations of `top`, `center`, `bottom` and `left`, `center`, `right` with the exception of `center center`. +Accepted positions are combinations of `top`, `center`, `bottom` and `left`, `center`, `right`. Possible triggers are `hover` and `click`. @@ -435,7 +435,7 @@ Possible triggers are `hover` and `click`. tooltip: 'This is a marker' // tooltip with default position and style tooltip: { // tooltip with custom position - content : 'This is marker', + content: 'This is marker', position: 'bottom left', } diff --git a/example/components.html b/example/components.html index 3896ad752..397371b84 100644 --- a/example/components.html +++ b/example/components.html @@ -79,7 +79,20 @@

Custom panel

{ content : 'Tooltip', onClick : () => { - const position = ['top center', 'top left', 'top right', 'bottom center', 'bottom left', 'bottom right', 'center left', 'center right'][Math.floor(Math.random() * 8)]; + const position = [ + 'top', + 'top left', + 'top right', + 'bottom', + 'bottom left', + 'bottom right', + 'left', + 'right', + 'left top', + 'left bottom', + 'right top', + 'right bottom', + ][Math.floor(Math.random() * 12)]; viewer.tooltip.create({ top : Math.random() * (document.body.offsetHeight - 200) + 100, left : Math.random() * (document.body.offsetWidth - 200) + 100, diff --git a/example/plugin-markers.html b/example/plugin-markers.html index 3a6bdfa99..38c9cff2c 100644 --- a/example/plugin-markers.html +++ b/example/plugin-markers.html @@ -225,7 +225,7 @@

Lorem ipsum

}, tooltip : { content : 'Simple polygon', - position: 'right bottom', + position: 'bottom right', }, }); @@ -248,7 +248,7 @@

Lorem ipsum

}, tooltip : { content : 'Polygon with image background', - position: 'right bottom', + position: 'bottom right', }, }); diff --git a/src/components/Tooltip.js b/src/components/Tooltip.js index 2f3d56632..02e969383 100644 --- a/src/components/Tooltip.js +++ b/src/components/Tooltip.js @@ -1,6 +1,6 @@ import { EVENTS } from '../data/constants'; import { PSVError } from '../PSVError'; -import { addClasses, cleanPosition } from '../utils'; +import { addClasses, cleanPosition, positionIsOrdered } from '../utils'; import { AbstractComponent } from './AbstractComponent'; const STATE = { NONE: 0, SHOWING: 1, HIDING: 2, READY: 3 }; @@ -35,7 +35,7 @@ export class Tooltip extends AbstractComponent { /** * @param {PSV.Viewer} psv - * @param {{arrow: number, offset: number}} size + * @param {{arrow: number, border: number}} size */ constructor(psv, size) { super(psv, 'psv-tooltip'); @@ -43,7 +43,7 @@ export class Tooltip extends AbstractComponent { /** * @override * @property {number} arrow - * @property {number} offset + * @property {number} border * @property {number} width * @property {number} height * @property {string} pos @@ -169,6 +169,13 @@ export class Tooltip extends AbstractComponent { throw new PSVError('Uninitialized tooltip cannot be moved'); } + if (!config.box) { + config.box = { + width : 0, + height: 0, + }; + } + this.config = config; const t = this.container; @@ -176,7 +183,7 @@ export class Tooltip extends AbstractComponent { // compute size const style = { - posClass : config.position ? cleanPosition(config.position, false) : ['top', 'center'], + posClass : cleanPosition(config.position, { allowCenter: false, cssOrder: false }) || ['top', 'center'], width : this.prop.width, height : this.prop.height, top : 0, @@ -189,24 +196,28 @@ export class Tooltip extends AbstractComponent { this.__computeTooltipPosition(style, config); // correct position if overflow - let refresh = false; - if (style.top < this.prop.offset) { - style.posClass[0] = 'bottom'; - refresh = true; + let swapY = null; + let swapX = null; + if (style.top < 0) { + swapY = 'bottom'; } - else if (style.top + style.height > this.psv.prop.size.height - this.prop.offset) { - style.posClass[0] = 'top'; - refresh = true; + else if (style.top + style.height > this.psv.prop.size.height) { + swapY = 'top'; } - if (style.left < this.prop.offset) { - style.posClass[1] = 'right'; - refresh = true; + if (style.left < 0) { + swapX = 'right'; } - else if (style.left + style.width > this.psv.prop.size.width - this.prop.offset) { - style.posClass[1] = 'left'; - refresh = true; + else if (style.left + style.width > this.psv.prop.size.width) { + swapX = 'left'; } - if (refresh) { + if (swapX || swapY) { + const ordered = positionIsOrdered(style.posClass); + if (swapY) { + style.posClass[ordered ? 0 : 1] = swapY; + } + if (swapX) { + style.posClass[ordered ? 1 : 0] = swapX; + } this.__computeTooltipPosition(style, config); } @@ -268,62 +279,87 @@ export class Tooltip extends AbstractComponent { * @private */ __computeTooltipPosition(style, config) { - let topBottom = false; - - if (!config.box) { - config.box = { - width : 0, - height: 0, - }; - } - - switch (style.posClass[0]) { - case 'bottom': - style.top = config.top + config.box.height + this.prop.offset + this.prop.arrow; - style.arrowTop = -this.prop.arrow * 2; - topBottom = true; + const arrow = this.prop.arrow; + const top = config.top; + const height = style.height; + const left = config.left; + const width = style.width; + const offsetSide = arrow + this.prop.border; + const offsetX = config.box.width / 2 + arrow * 2; + const offsetY = config.box.height / 2 + arrow * 2; + + switch (style.posClass.join('-')) { + case 'top-left': + style.top = top - offsetY - height; + style.left = left + offsetSide - width; + style.arrowTop = height; + style.arrowLeft = width - offsetSide - arrow; break; - - case 'center': - style.top = config.top + config.box.height / 2 - style.height / 2; - style.arrowTop = style.height / 2 - this.prop.arrow; + case 'top-center': + style.top = top - offsetY - height; + style.left = left - width / 2; + style.arrowTop = height; + style.arrowLeft = width / 2 - arrow; break; - - case 'top': - style.top = config.top - style.height - this.prop.offset - this.prop.arrow; - style.arrowTop = style.height; - topBottom = true; + case 'top-right': + style.top = top - offsetY - height; + style.left = left - offsetSide; + style.arrowTop = height; + style.arrowLeft = arrow; break; - - // no default - } - - switch (style.posClass[1]) { - case 'right': - if (topBottom) { - style.left = config.left + config.box.width / 2 - this.prop.offset - this.prop.arrow; - style.arrowLeft = this.prop.offset; - } - else { - style.left = config.left + config.box.width + this.prop.offset + this.prop.arrow; - style.arrowLeft = -this.prop.arrow * 2; - } + case 'bottom-left': + style.top = top + offsetY; + style.left = left + offsetSide - width; + style.arrowTop = -arrow * 2; + style.arrowLeft = width - offsetSide - arrow; break; - - case 'center': - style.left = config.left + config.box.width / 2 - style.width / 2; - style.arrowLeft = style.width / 2 - this.prop.arrow; + case 'bottom-center': + style.top = top + offsetY; + style.left = left - width / 2; + style.arrowTop = -arrow * 2; + style.arrowLeft = width / 2 - arrow; break; - - case 'left': - if (topBottom) { - style.left = config.left - style.width + config.box.width / 2 + this.prop.offset + this.prop.arrow; - style.arrowLeft = style.width - this.prop.offset - this.prop.arrow * 2; - } - else { - style.left = config.left - style.width - this.prop.offset - this.prop.arrow; - style.arrowLeft = style.width; - } + case 'bottom-right': + style.top = top + offsetY; + style.left = left - offsetSide; + style.arrowTop = -arrow * 2; + style.arrowLeft = arrow; + break; + case 'left-top': + style.top = top + offsetSide - height; + style.left = left - offsetX - width; + style.arrowTop = height - offsetSide - arrow; + style.arrowLeft = width; + break; + case 'center-left': + style.top = top - height / 2; + style.left = left - offsetX - width; + style.arrowTop = height / 2 - arrow; + style.arrowLeft = width; + break; + case 'left-bottom': + style.top = top - offsetSide; + style.left = left - offsetX - width; + style.arrowTop = arrow; + style.arrowLeft = width; + break; + case 'right-top': + style.top = top + offsetSide - height; + style.left = left + offsetX; + style.arrowTop = height - offsetSide - arrow; + style.arrowLeft = -arrow * 2; + break; + case 'center-right': + style.top = top - height / 2; + style.left = left + offsetX; + style.arrowTop = height / 2 - arrow; + style.arrowLeft = -arrow * 2; + break; + case 'right-bottom': + style.top = top - offsetSide; + style.left = left + offsetX; + style.arrowTop = arrow; + style.arrowLeft = -arrow * 2; break; // no default diff --git a/src/plugins/compass/index.js b/src/plugins/compass/index.js index 1a9069204..dab4911aa 100644 --- a/src/plugins/compass/index.js +++ b/src/plugins/compass/index.js @@ -47,15 +47,14 @@ export class CompassPlugin extends AbstractPlugin { */ this.config = { size : '120px', - position : 'top left', backgroundSvg : compass, coneColor : 'rgba(255, 255, 255, 0.5)', navigation : true, navigationColor: 'rgba(255, 0, 0, 0.2)', hotspotColor : 'rgba(0, 0, 0, 0.5)', ...options, + position : utils.cleanPosition(options.position, { allowCenter: true, cssOrder: true }) || ['top', 'left'], }; - this.config.position = utils.cleanPosition(this.config.position, 'top left'); /** * @private diff --git a/src/plugins/markers/Marker.js b/src/plugins/markers/Marker.js index 180cd931c..ee2a8d251 100644 --- a/src/plugins/markers/Marker.js +++ b/src/plugins/markers/Marker.js @@ -312,15 +312,14 @@ export class Marker { }; if (this.isPoly()) { - config.box = { // separate the tooltip from the cursor - width : this.psv.tooltip.size.arrow * 2, - height: this.psv.tooltip.size.arrow * 2, - }; - if (mousePosition) { const viewerPos = utils.getPosition(this.psv.container); - config.top = mousePosition.clientY - viewerPos.top - this.psv.tooltip.size.arrow / 2; - config.left = mousePosition.clientX - viewerPos.left - this.psv.tooltip.size.arrow; + config.top = mousePosition.clientY - viewerPos.top; + config.left = mousePosition.clientX - viewerPos.left; + config.box = { // separate the tooltip from the cursor + width : 20, + height: 20, + }; } else { config.top = this.props.position2D.y; @@ -328,8 +327,8 @@ export class Marker { } } else { - config.top = this.props.position2D.y; - config.left = this.props.position2D.x; + config.top = this.props.position2D.y + this.props.height / 2; + config.left = this.props.position2D.x + this.props.width / 2; config.box = { width : this.props.width, height: this.props.height, diff --git a/src/services/TooltipRenderer.js b/src/services/TooltipRenderer.js index 7e2ff496d..e06923d65 100644 --- a/src/services/TooltipRenderer.js +++ b/src/services/TooltipRenderer.js @@ -15,18 +15,18 @@ export class TooltipRenderer extends AbstractService { constructor(psv) { super(psv); - const testTooltip = new Tooltip(this.psv); + const testTooltip = new Tooltip(this.psv, { arrow: 0, border: 0 }); /** * @summary Computed static sizes * @member {Object} * @package - * @property {number} arrowSize - * @property {number} offset + * @property {number} arrow + * @property {number} border */ this.size = { arrow : parseInt(getStyle(testTooltip.arrow, 'borderTopWidth'), 10), - offset: parseInt(getStyle(testTooltip.container, 'outlineWidth'), 10), + border: parseInt(getStyle(testTooltip.container, 'borderTopLeftRadius'), 10), }; testTooltip.destroy(); diff --git a/src/styles/tooltip.scss b/src/styles/tooltip.scss index 712cfd327..b4ab7509e 100644 --- a/src/styles/tooltip.scss +++ b/src/styles/tooltip.scss @@ -9,13 +9,10 @@ border-radius: $psv-tooltip-radius; padding: $psv-tooltip-padding; opacity: 0; - transition-property: opacity; + transition-property: opacity, transform; transition-timing-function: ease-in-out; transition-duration: $psv-tooltip-animate-delay; - // this is used to let the JS aware of the animation offset - outline: $psv-tooltip-animate-offset solid transparent; - &-content { color: $psv-tooltip-text-color; font: $psv-tooltip-font; @@ -29,84 +26,80 @@ border: $psv-tooltip-arrow-size solid transparent; } - &--bottom-center { - box-shadow: 0 $psv-tooltip-shadow-offset 0 $psv-tooltip-shadow-color; - transform: translate3d(0, -$psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; + &--top-left, + &--top-center, + &--top-right { + transform: translate3d(0, $psv-tooltip-animate-offset, 0); .psv-tooltip-arrow { - border-bottom-color: $psv-tooltip-background-color; + border-top-color: $psv-tooltip-background-color; } } - &--center-left { - box-shadow: #{-$psv-tooltip-shadow-offset} 0 0 $psv-tooltip-shadow-color; - transform: translate3d($psv-tooltip-animate-offset, 0, 0); - transition-property: opacity, transform; + &--bottom-left, + &--bottom-center, + &--bottom-right { + transform: translate3d(0, -$psv-tooltip-animate-offset, 0); .psv-tooltip-arrow { - border-left-color: $psv-tooltip-background-color; + border-bottom-color: $psv-tooltip-background-color; } } - &--top-center { - box-shadow: 0 #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; - transform: translate3d(0, $psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; + &--left-top, + &--center-left, + &--left-bottom { + transform: translate3d($psv-tooltip-animate-offset, 0, 0); .psv-tooltip-arrow { - border-top-color: $psv-tooltip-background-color; + border-left-color: $psv-tooltip-background-color; } } - &--center-right { - box-shadow: $psv-tooltip-shadow-offset 0 0 $psv-tooltip-shadow-color; + &--right-top, + &--center-right, + &--right-bottom { transform: translate3d(-$psv-tooltip-animate-offset, 0, 0); - transition-property: opacity, transform; .psv-tooltip-arrow { border-right-color: $psv-tooltip-background-color; } } + &--left-top, + &--top-left { + box-shadow: #{-$psv-tooltip-shadow-offset} #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; + } + + &--top-center { + box-shadow: 0 #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; + } + + &--right-top, + &--top-right { + box-shadow: $psv-tooltip-shadow-offset #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; + } + + &--left-bottom, &--bottom-left { box-shadow: #{-$psv-tooltip-shadow-offset} $psv-tooltip-shadow-offset 0 $psv-tooltip-shadow-color; - transform: translate3d(0, -$psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; + } - .psv-tooltip-arrow { - border-bottom-color: $psv-tooltip-background-color; - } + &--bottom-center { + box-shadow: 0 $psv-tooltip-shadow-offset 0 $psv-tooltip-shadow-color; } + &--right-bottom, &--bottom-right { box-shadow: $psv-tooltip-shadow-offset $psv-tooltip-shadow-offset 0 $psv-tooltip-shadow-color; - transform: translate3d(0, -$psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; - - .psv-tooltip-arrow { - border-bottom-color: $psv-tooltip-background-color; - } } - &--top-left { - box-shadow: #{-$psv-tooltip-shadow-offset} #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; - transform: translate3d(0, $psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; - - .psv-tooltip-arrow { - border-top-color: $psv-tooltip-background-color; - } + &--center-left { + box-shadow: #{-$psv-tooltip-shadow-offset} 0 0 $psv-tooltip-shadow-color; } - &--top-right { - box-shadow: $psv-tooltip-shadow-offset #{-$psv-tooltip-shadow-offset} 0 $psv-tooltip-shadow-color; - transform: translate3d(0, $psv-tooltip-animate-offset, 0); - transition-property: opacity, transform; - - .psv-tooltip-arrow { - border-top-color: $psv-tooltip-background-color; - } + &--center-right { + box-shadow: $psv-tooltip-shadow-offset 0 0 $psv-tooltip-shadow-color; } &--visible { diff --git a/src/utils/psv.js b/src/utils/psv.js index b6c1e882b..660d1ae88 100644 --- a/src/utils/psv.js +++ b/src/utils/psv.js @@ -152,38 +152,85 @@ export function parsePosition(value) { * @readonly * @private */ -const LEFT_MAP = { 0: 'left', 0.5: 'center', 1: 'right' }; +const X_VALUES = ['left', 'center', 'right']; /** * @readonly * @private */ -const TOP_MAP = { 0: 'top', 0.5: 'center', 1: 'bottom' }; +const Y_VALUES = ['top', 'center', 'bottom']; +/** + * @readonly + * @private + */ +const POS_VALUES = [...X_VALUES, ...Y_VALUES]; +/** + * @readonly + * @private + */ +const CENTER = 'center'; /** * @summary Parse a CSS-like position into an array of position keywords among top, bottom, left, right and center * @memberOf PSV.utils * @param {string | string[]} value - * @param {boolean} [allowCenter=true] + * @param {object} [options] + * @param {boolean} [options.allowCenter=true] allow "center center" + * @param {boolean} [options.cssOrder=true] force CSS order (y axis then x axis) * @return {string[]} */ -export function cleanPosition(value, allowCenter = true) { +export function cleanPosition(value, { allowCenter, cssOrder } = { allowCenter: true, cssOrder: true }) { + if (!value) { + return null; + } + if (typeof value === 'string') { - const tempPos = parsePosition(value); + value = value.split(' '); + } - if (!(tempPos.x in LEFT_MAP) || !(tempPos.y in TOP_MAP)) { - throw new PSVError(`Unable to parse position "${value}"`); + if (value.length === 1) { + if (value[0] === CENTER) { + value = [CENTER, CENTER]; } + else if (X_VALUES.indexOf(value[0]) !== -1) { + value = [CENTER, value[0]]; + } + else if (Y_VALUES.indexOf(value[0]) !== -1) { + value = [value[0], CENTER]; + } + } - value = [TOP_MAP[tempPos.y], LEFT_MAP[tempPos.x]]; + if (value.length !== 2 || POS_VALUES.indexOf(value[0]) === -1 || POS_VALUES.indexOf(value[1]) === -1) { + logWarn(`Unparsable position ${value}`); + return null; } - if (!allowCenter && value[0] === 'center' && value[1] === 'center') { - throw new PSVError('Unable to parse position "center center"'); + if (!allowCenter && value[0] === CENTER && value[1] === CENTER) { + logWarn(`Invalid position center center`); + return null; + } + + if (cssOrder && !positionIsOrdered(value)) { + value = [value[1], value[0]]; + } + if (value[1] === CENTER && X_VALUES.indexOf(value[0]) !== -1) { + value = [CENTER, value[0]]; + } + if (value[0] === CENTER && Y_VALUES.indexOf(value[1]) !== -1) { + value = [value[1], CENTER]; } return value; } +/** + * @summary Checks if an array of two positions is ordered (y axis then x axis) + * @param {string[]} value + * @return {boolean} + */ +export function positionIsOrdered(value) { + return Y_VALUES.indexOf(value[0]) !== -1 && X_VALUES.indexOf(value[1]) !== -1; +} + /** * @summary Parses an speed * @memberOf PSV.utils diff --git a/src/utils/psv.spec.js b/src/utils/psv.spec.js index 6fb8cf781..aa4265ba2 100644 --- a/src/utils/psv.spec.js +++ b/src/utils/psv.spec.js @@ -1,6 +1,6 @@ import assert from 'assert'; -import { parseAngle, parsePosition, parseSpeed, getXMPValue, cleanPosition } from './psv'; +import { cleanPosition, getXMPValue, parseAngle, parsePosition, parseSpeed } from './psv'; describe('utils:psv:parseAngle', () => { it('should normalize number', () => { @@ -320,20 +320,34 @@ describe('utils:psv:cleanPosition', () => { it('should clean various formats', () => { assert.deepStrictEqual(cleanPosition('top right'), ['top', 'right']); assert.deepStrictEqual(cleanPosition('right top'), ['top', 'right']); + assert.deepStrictEqual(cleanPosition(['top', 'right']), ['top', 'right']); + }); + + it('should add missing center', () => { assert.deepStrictEqual(cleanPosition('top'), ['top', 'center']); assert.deepStrictEqual(cleanPosition('left'), ['center', 'left']); - assert.deepStrictEqual(cleanPosition(['top', 'right']), ['top', 'right']); + assert.deepStrictEqual(cleanPosition('center'), ['center', 'center']); }); - it('should dissallow center', () => { - assert.deepStrictEqual(cleanPosition('top center', false), ['top', 'center']); + it('should dissallow all center', () => { + assert.strictEqual(cleanPosition('center center', { allowCenter: false }), null); + assert.strictEqual(cleanPosition('center', { allowCenter: false }), null); + }); - assert.throws(() => { - cleanPosition('center center', false); - }); + it('should return null on unparsable values', () => { + assert.strictEqual(cleanPosition('foo bar'), null); + assert.strictEqual(cleanPosition('TOP CENTER'), null); + assert.strictEqual(cleanPosition(''), null); + assert.strictEqual(cleanPosition(undefined), null); + }); + + it('should allow XY order', () => { + assert.deepStrictEqual(cleanPosition('right top', { cssOrder: false }), ['right', 'top']); + assert.deepStrictEqual(cleanPosition(['top', 'right'], { cssOrder: false }), ['top', 'right']); }); - it('should not fail on unparsable values', () => { - assert.deepStrictEqual(cleanPosition('foo bar'), ['center', 'center']); + it('should always order with center', () => { + assert.deepStrictEqual(cleanPosition('center top'), ['top', 'center']); + assert.deepStrictEqual(cleanPosition('left center'), ['center', 'left']); }); }); diff --git a/types/plugins/markers/index.d.ts b/types/plugins/markers/index.d.ts index 779850a89..2828f98bd 100644 --- a/types/plugins/markers/index.d.ts +++ b/types/plugins/markers/index.d.ts @@ -36,7 +36,7 @@ export type MarkerProperties = Partial & { width?: number; height?: number; orientation?: 'front' | 'horizontal' | 'vertical-left' | 'vertical-right'; - scale?: number | [number, number] | { zoom?: [number, number], longitude?: [number, number] }; + scale?: [number, number] | { zoom?: [number, number], longitude?: [number, number] }; opacity?: number; className?: string; style?: Record; diff --git a/types/utils/psv.d.ts b/types/utils/psv.d.ts index a5b7f36df..f960f0b7c 100644 --- a/types/utils/psv.d.ts +++ b/types/utils/psv.d.ts @@ -25,11 +25,8 @@ export function parsePosition(value: string | Point): Point; /** * @summary Parse a CSS-like position into an array of position keywords among top, bottom, left, right and center - * @param {string | string[]} value - * @param {string} defaultValue - * @param {boolean} [allowCenter=true] */ -export function cleanPosition(value: string | string[], defaultValue: string, allowCenter?): string[]; +export function cleanPosition(value: string | string[], options?: { allowCenter: boolean, cssOrder: boolean }): string[]; /** * @summary Parses an speed From 364fa0cbdbc7b581d5f71a61e2a2727b3841a2f0 Mon Sep 17 00:00:00 2001 From: Damien Sorel Date: Thu, 22 Sep 2022 13:13:48 +0200 Subject: [PATCH 05/14] Close #759 markers: add `zoomLvl` marker option --- .github/ISSUE_TEMPLATE.md | 7 +- docs/plugins/plugin-markers.md | 22 ++++-- example/plugin-markers.html | 114 ++++++++++++++++--------------- src/Viewer.js | 2 +- src/plugins/markers/index.js | 3 +- types/plugins/markers/index.d.ts | 2 + 6 files changed, 83 insertions(+), 67 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5461d3808..375b5d929 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,7 +1,8 @@ **Issues guidelines** -- **Indicate your Photo-Sphere-Viewer, three.js and web browser versions** -- Please search in the [documentation](http://photo-sphere-viewer.js.org) before asking. -- Any issue without enough details won't get any answer and will be closed. +- Speak English or French. +- Indicate your Photo-Sphere-Viewer, three.js and web browser versions. +- Search in the [documentation](http://photo-sphere-viewer.js.org) before asking. - Help requests must be exhaustive, precise and come with some code explaining the need (use Markdown code highlight). - Bug reports must come with a simple test case, preferably on jsFiddle, Plunker, etc. +- Any issue without enough details won't get any answer and will be closed. diff --git a/docs/plugins/plugin-markers.md b/docs/plugins/plugin-markers.md index 67859addc..971fa1c5c 100644 --- a/docs/plugins/plugin-markers.md +++ b/docs/plugins/plugin-markers.md @@ -85,6 +85,7 @@ const viewer = new PhotoSphereViewer.Viewer({ width: 32, height: 32, anchor: 'bottom center', + zoomLvl: 100, tooltip: 'A image marker. Click me!', content: document.getElementById('lorem-content').innerHTML }, @@ -215,7 +216,7 @@ markersPlugin.on('select-marker', (e, marker, data) => { sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

- +

Header Level 2

@@ -417,6 +418,13 @@ And use it in your marker : `fill: 'url(#image)'`. Defines where the marker is placed toward its defined position. Any CSS position is valid like `bottom center` or `20% 80%`. _(This option is ignored for polygons and polylines)._ +#### `zoomLvl` +- type: `number` +- default: `undefind` + +The zoom level which will be applied when calling `gotoMarker()` method or when clicking on the marker in the list. +If not provided, the current zoom level is kept. + #### `visible` - type: `boolean` - default: `true` @@ -450,15 +458,15 @@ tooltip: { // tooltip with a custom class shown on click If `trigger` is set to `'click'` you won't be able to display a `content` in the side panel. ::: -#### `listContent` +#### `content` - type: `string` -The name that appears in the list of markers. If not provided, the tooltip content will be used. +HTML content that will be displayed on the side panel when the marker is clicked. -#### `content` +#### `listContent` - type: `string` -HTML content that will be displayed on the side panel when the marker is clicked. +The name that appears in the list of markers. If not provided, the tooltip content will be used. #### `hideList` - type: `boolean` @@ -516,9 +524,9 @@ Removes all markers. Returns the last marker clicked by the user. -#### `gotoMarker(id, speed): Animation` +#### `gotoMarker(id[, speed]): Animation` -Moves the view to center a specific marker, with optional [animation](../guide/methods.md#animate-options-animation). +Moves the view to face a specific marker. ```js markersPlugin.gotoMarker('marker-1', 1500) diff --git a/example/plugin-markers.html b/example/plugin-markers.html index 38c9cff2c..c9d7810af 100644 --- a/example/plugin-markers.html +++ b/example/plugin-markers.html @@ -108,6 +108,7 @@

Header Level 3

caption : 'Parc national du Mercantour © Damien Sorel', loadingImg: 'assets/photosphere-logo.gif', navbar : [ + 'zoom', 'move', 'markers', 'markersList', { content : '💬', @@ -126,25 +127,6 @@

Header Level 3

markers: (() => { const a = []; - // add markers all hover the sphere - for (let i = 0; i < Math.PI * 2; i += Math.PI / 4) { - for (let j = -Math.PI / 2 + Math.PI / 4; j < Math.PI / 2; j += Math.PI / 4) { - a.push({ - id : '#' + a.length, - tooltip : '#' + a.length, - latitude : j, - longitude: i, - image : 'assets/pin-red.png', - width : 32, - height : 32, - anchor : 'bottom center', - data : { - deletable: true, - }, - }); - } - } - // marker with content and tooltip a.push({ id : 'content', @@ -177,10 +159,12 @@

Lorem ipsum

}, latitude : 0.11, longitude: -0.35, + zoomLvl : 100, image : 'assets/pin-blue.png', width : 32, height : 32, anchor : 'bottom center', + listContent: 'Lorem ipsum', }); // big polygon to test the handling of points behind the camera @@ -265,6 +249,29 @@

Lorem ipsum

tooltip : 'Polyline', }); + // embedded images + a.push({ + id : 'imageLayer', + imageLayer: 'assets/tent.png', + width : 120, + height : 94, + longitude : -0.45, + latitude : -0.1, + tooltip : 'Image embedded in the scene', + }); + + a.push({ + id : 'imageLayerOrient', + imageLayer : 'assets/target.png', + width : 120, + height : 120, + latitude : -0.2, + longitude : 0.27, + opacity : 0.8, + orientation: 'horizontal', + tooltip : 'Image embedded in the scene with "horizontal" orientation', + }); + // HTML & image markers a.push({ id : 'html-img-demo', @@ -272,7 +279,7 @@

Lorem ipsum

scale : [0.5, 1.5], className: 'demo-label', longitude: 0.5, - latitude : -0.48, + latitude : -0.42, hideList : true, }); @@ -281,8 +288,8 @@

Lorem ipsum

image : 'assets/photosphere-logo.gif', width : 100, height : 100, - longitude : 0.60, - latitude : -0.35, + longitude : 0.56, + latitude : -0.32, listContent: 'An animated gif', }); @@ -297,29 +304,7 @@

Lorem ipsum

textAlign : 'center', }, longitude: 0.45, - latitude : -0.4, - }); - - a.push({ - id : 'imageLayer', - imageLayer: 'assets/tent.png', - width : 120, - height : 94, - longitude : -0.45, - latitude : -0.1, - tooltip : 'Image embedded in the scene', - }); - - a.push({ - id : 'imageLayerOrient', - imageLayer : 'assets/target.png', - width : 120, - height : 120, - latitude : -0.2, - longitude : 0.27, - opacity : 0.8, - orientation: 'horizontal', - tooltip : 'Image embedded in the scene with "horizontal" orientation', + latitude : -0.38, }); // SVG markers @@ -329,7 +314,7 @@

Lorem ipsum

scale : [0.5, 1.5], className: 'demo-label', longitude: -0.5, - latitude : -0.48, + latitude : -0.42, hideList : true, }); @@ -343,8 +328,8 @@

Lorem ipsum

strokeWidth: '2px', }, longitude: -0.5, - latitude : -0.28, - anchor : 'center right', + latitude : -0.32, + anchor : 'bottom right', }); a.push({ @@ -357,8 +342,8 @@

Lorem ipsum

strokeWidth: '2px', }, longitude: -0.5, - latitude : -0.28, - anchor : 'center left', + latitude : -0.32, + anchor : 'bottom left', }); a.push({ @@ -371,8 +356,8 @@

Lorem ipsum

strokeWidth: '2px', }, longitude: -0.5, - latitude : -0.38, - anchor : 'center right', + latitude : -0.32, + anchor : 'top right', }); a.push({ @@ -385,8 +370,8 @@

Lorem ipsum

strokeWidth: '2px', }, longitude: -0.5, - latitude : -0.38, - anchor : 'center left', + latitude : -0.32, + anchor : 'top left', }); // Scalling markers @@ -396,7 +381,7 @@

Lorem ipsum

scale : [0.5, 1.5], className: 'demo-label', longitude: 0, - latitude : -0.48, + latitude : -0.47, hideList : true, }); @@ -440,6 +425,25 @@

Lorem ipsum

latitude : -0.4, }); + // add markers all hover the sphere + for (let i = 0; i < Math.PI * 2; i += Math.PI / 4) { + for (let j = -Math.PI / 2 + Math.PI / 4; j < Math.PI / 2; j += Math.PI / 4) { + a.push({ + id : '#' + a.length, + tooltip : '#' + a.length, + latitude : j, + longitude: i, + image : 'assets/pin-red.png', + width : 32, + height : 32, + anchor : 'bottom center', + data : { + deletable: true, + }, + }); + } + } + return a; })(), }], diff --git a/src/Viewer.js b/src/Viewer.js index 27eb0e279..02481372e 100644 --- a/src/Viewer.js +++ b/src/Viewer.js @@ -832,7 +832,7 @@ export class Viewer extends EventEmitter { this.__stopAll(); const positionProvided = isExtendedPosition(options); - const zoomProvided = 'zoom' in options; + const zoomProvided = options.zoom !== undefined; const animProperties = {}; let duration; diff --git a/src/plugins/markers/index.js b/src/plugins/markers/index.js index ff17d9c96..60ff20420 100644 --- a/src/plugins/markers/index.js +++ b/src/plugins/markers/index.js @@ -443,7 +443,8 @@ export class MarkersPlugin extends AbstractPlugin { return this.psv.animate({ ...marker.props.position, - speed, + zoom : marker.config.zoomLvl, + speed: speed, }) .then(() => { this.trigger(EVENTS.GOTO_MARKER_DONE, marker); diff --git a/types/plugins/markers/index.d.ts b/types/plugins/markers/index.d.ts index 2828f98bd..7aefa69ed 100644 --- a/types/plugins/markers/index.d.ts +++ b/types/plugins/markers/index.d.ts @@ -42,9 +42,11 @@ export type MarkerProperties = Partial & { style?: Record; svgStyle?: Record; anchor?: string; + zoomLvl?: number; visible?: boolean; tooltip?: string | { content: string, position?: string, className?: string, trigger?: 'hover' | 'click' }; content?: string; + listContent?: string; hideList?: boolean; data?: any; }; From 6762f28ce23cbbd9de2b446ae4dcb9b687349b80 Mon Sep 17 00:00:00 2001 From: Damien Sorel Date: Fri, 23 Sep 2022 17:05:53 +0200 Subject: [PATCH 06/14] Close #761 tiles: use file loader if HTTP headers are provided --- src/adapters/cubemap-tiles/index.js | 37 ++++++++++++++------- src/adapters/equirectangular-tiles/index.js | 37 ++++++++++++++------- src/services/TextureLoader.js | 6 ++-- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/adapters/cubemap-tiles/index.js b/src/adapters/cubemap-tiles/index.js index 102c9ec57..f2b674a2b 100644 --- a/src/adapters/cubemap-tiles/index.js +++ b/src/adapters/cubemap-tiles/index.js @@ -132,12 +132,17 @@ export class CubemapTilesAdapter extends CubemapAdapter { * @member {external:THREE.ImageLoader} * @private */ - this.loader = new ImageLoader(); - if (this.psv.config.withCredentials) { - this.loader.setWithCredentials(true); + this.loader = null; + + if (this.psv.config.requestHeaders) { + utils.logWarn('CubemapTilesAdapter fallbacks to file loader because "requestHeaders" where provided. ' + + 'Consider removing "requestHeaders" if you experience performances issues.'); } - if (this.psv.config.requestHeaders && typeof this.psv.config.requestHeaders === 'object') { - this.loader.setRequestHeader(this.psv.config.requestHeaders); + else { + this.loader = new ImageLoader(); + if (this.psv.config.withCredentials) { + this.loader.setWithCredentials(true); + } } this.psv.on(CONSTANTS.EVENTS.POSITION_UPDATED, this); @@ -447,13 +452,7 @@ export class CubemapTilesAdapter extends CubemapAdapter { } const url = panorama.tileUrl(CUBE_HASHMAP[tile.face], col, row); - if (this.psv.config.requestHeaders && typeof this.psv.config.requestHeaders === 'function') { - this.loader.setRequestHeader(this.psv.config.requestHeaders(url)); - } - - return new Promise((resolve, reject) => { - this.loader.load(url, resolve, undefined, reject); - }) + return this.__loadImage(url) .then((image) => { if (!task.isCancelled()) { const material = new MeshBasicMaterial({ map: utils.createTexture(image) }); @@ -472,6 +471,20 @@ export class CubemapTilesAdapter extends CubemapAdapter { }); } + /** + * @private + */ + __loadImage(url) { + if (this.loader) { + return new Promise((resolve, reject) => { + this.loader.load(url, resolve, undefined, reject); + }); + } + else { + return this.psv.textureLoader.loadImage(url); + } + } + /** * @summary Applies a new texture to the faces * @param {int} face diff --git a/src/adapters/equirectangular-tiles/index.js b/src/adapters/equirectangular-tiles/index.js index b5211234a..e7504f566 100644 --- a/src/adapters/equirectangular-tiles/index.js +++ b/src/adapters/equirectangular-tiles/index.js @@ -161,12 +161,17 @@ export class EquirectangularTilesAdapter extends EquirectangularAdapter { * @member {external:THREE.ImageLoader} * @private */ - this.loader = new ImageLoader(); - if (this.psv.config.withCredentials) { - this.loader.setWithCredentials(true); + this.loader = null; + + if (this.psv.config.requestHeaders) { + utils.logWarn('EquirectangularTilesAdapter fallbacks to file loader because "requestHeaders" where provided. ' + + 'Consider removing "requestHeaders" if you experience performances issues.'); } - if (this.psv.config.requestHeaders && typeof this.psv.config.requestHeaders === 'object') { - this.loader.setRequestHeader(this.psv.config.requestHeaders); + else { + this.loader = new ImageLoader(); + if (this.psv.config.withCredentials) { + this.loader.setWithCredentials(true); + } } this.psv.on(CONSTANTS.EVENTS.POSITION_UPDATED, this); @@ -579,13 +584,7 @@ export class EquirectangularTilesAdapter extends EquirectangularAdapter { const panorama = this.psv.config.panorama; const url = panorama.tileUrl(tile.col, tile.row); - if (this.psv.config.requestHeaders && typeof this.psv.config.requestHeaders === 'function') { - this.loader.setRequestHeader(this.psv.config.requestHeaders(url)); - } - - return new Promise((resolve, reject) => { - this.loader.load(url, resolve, undefined, reject); - }) + return this.__loadImage(url) .then((image) => { if (!task.isCancelled()) { const material = new MeshBasicMaterial({ map: utils.createTexture(image) }); @@ -604,6 +603,20 @@ export class EquirectangularTilesAdapter extends EquirectangularAdapter { }); } + /** + * @private + */ + __loadImage(url) { + if (this.loader) { + return new Promise((resolve, reject) => { + this.loader.load(url, resolve, undefined, reject); + }); + } + else { + return this.psv.textureLoader.loadImage(url); + } + } + /** * @summary Applies a new texture to the faces * @param {int} col diff --git a/src/services/TextureLoader.js b/src/services/TextureLoader.js index 956e1579b..d3fda5eb9 100644 --- a/src/services/TextureLoader.js +++ b/src/services/TextureLoader.js @@ -58,13 +58,13 @@ export class TextureLoader extends AbstractService { return new Promise((resolve, reject) => { let progress = 0; - onProgress && onProgress(progress); + onProgress?.(progress); this.loader.load( url, (result) => { progress = 100; - onProgress && onProgress(progress); + onProgress?.(progress); resolve(result); }, (e) => { @@ -72,7 +72,7 @@ export class TextureLoader extends AbstractService { const newProgress = e.loaded / e.total * 100; if (newProgress > progress) { progress = newProgress; - onProgress && onProgress(progress); + onProgress?.(progress); } } }, From 7a21f0e63d1fa71417a52d080cac2c81875d4df3 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 25 Sep 2022 20:18:56 +0200 Subject: [PATCH 07/14] doc: improve playground --- docs/.vuepress/components/Playground.vue | 613 ++++++++++++----------- 1 file changed, 331 insertions(+), 282 deletions(-) diff --git a/docs/.vuepress/components/Playground.vue b/docs/.vuepress/components/Playground.vue index cfeaaa1cc..b73f0178f 100644 --- a/docs/.vuepress/components/Playground.vue +++ b/docs/.vuepress/components/Playground.vue @@ -47,6 +47,7 @@ .playground-container .md-tabs-content { overflow-y: visible; height: 100% !important; + box-shadow: none; } .playground-container .md-title { @@ -57,179 +58,198 @@