photo-sphere-viewer
Version:
A JavaScript library to display Photo Sphere panoramas
236 lines (194 loc) • 5.96 kB
JavaScript
import { AbstractPlugin, CONSTANTS, DEFAULTS, PSVError, utils } from '../..';
import { EVENTS } from './constants';
/**
* @typedef {Object} PSV.plugins.ResolutionPlugin.Resolution
* @property {string} id
* @property {string} label
* @property {*} panorama
*/
/**
* @typedef {Object} PSV.plugins.ResolutionPlugin.Options
* @property {PSV.plugins.ResolutionPlugin.Resolution[]} resolutions - list of available resolutions
* @property {string} [defaultResolution] - the default resolution if no panorama is configured on the viewer
* @property {boolean} [showBadge=true] - show the resolution id as a badge on the settings button
*/
DEFAULTS.lang.resolution = 'Quality';
export { EVENTS } from './constants';
/**
* @summary Adds a setting to choose between multiple resolutions of the panorama.
* @extends PSV.plugins.AbstractPlugin
* @memberof PSV.plugins
*/
export class ResolutionPlugin extends AbstractPlugin {
static id = 'resolution';
static EVENTS = EVENTS;
/**
* @param {PSV.Viewer} psv
* @param {PSV.plugins.ResolutionPlugin.Options} options
*/
constructor(psv, options) {
super(psv);
/**
* @type {PSV.plugins.SettingsPlugin}
* @readonly
* @private
*/
this.settings = null;
/**
* @summary Available resolutions
* @member {PSV.plugins.ResolutionPlugin.Resolution[]}
*/
this.resolutions = [];
/**
* @summary Available resolutions
* @member {Object.<string, PSV.plugins.ResolutionPlugin.Resolution>}
* @private
*/
this.resolutionsById = {};
/**
* @type {Object}
* @property {string} resolution - Current resolution
* @private
*/
this.prop = {
resolution: null,
};
/**
* @type {PSV.plugins.ResolutionPlugin.Options}
*/
this.config = {
showBadge: true,
...options,
};
if (this.config.defaultResolution && this.psv.config.panorama) {
utils.logWarn('ResolutionPlugin, a defaultResolution was provided '
+ 'but a panorama is already configured on the viewer, '
+ 'the defaultResolution will be ignored.');
}
}
/**
* @package
*/
init() {
super.init();
this.settings = this.psv.getPlugin('settings');
if (!this.settings) {
throw new PSVError('Resolution plugin requires the Settings plugin');
}
this.settings.addSetting({
id : ResolutionPlugin.id,
type : 'options',
label : this.psv.config.lang.resolution,
current: () => this.prop.resolution,
options: () => this.__getSettingsOptions(),
apply : resolution => this.__setResolutionIfExists(resolution),
badge : !this.config.showBadge ? null : () => this.prop.resolution,
});
this.psv.on(CONSTANTS.EVENTS.PANORAMA_LOADED, this);
if (this.config.resolutions) {
this.setResolutions(this.config.resolutions, this.psv.config.panorama ? null : this.config.defaultResolution);
delete this.config.resolutions;
delete this.config.defaultResolution;
}
}
/**
* @package
*/
destroy() {
this.psv.off(CONSTANTS.EVENTS.PANORAMA_LOADED, this);
this.settings.removeSetting(ResolutionPlugin.id);
super.destroy();
}
/**
* @summary Handles events
* @param {Event} e
* @private
*/
handleEvent(e) {
if (e.type === CONSTANTS.EVENTS.PANORAMA_LOADED) {
this.__refreshResolution();
}
}
/**
* @summary Changes the available resolutions
* @param {PSV.plugins.ResolutionPlugin.Resolution[]} resolutions
* @param {string} [defaultResolution] - if not provided, the current panorama is kept
*/
setResolutions(resolutions, defaultResolution) {
this.resolutions = resolutions;
this.resolutionsById = {};
resolutions.forEach((resolution) => {
if (!resolution.id) {
throw new PSVError('Missing resolution id');
}
this.resolutionsById[resolution.id] = resolution;
});
// pick first resolution if no default provided and no current panorama
if (!this.psv.config.panorama && !defaultResolution) {
defaultResolution = resolutions[0].id;
}
// ensure the default resolution exists
if (defaultResolution && !this.resolutionsById[defaultResolution]) {
utils.logWarn(`Resolution ${defaultResolution} unknown`);
defaultResolution = resolutions[0].id;
}
if (defaultResolution) {
this.setResolution(defaultResolution);
}
this.__refreshResolution();
}
/**
* @summary Changes the current resolution
* @param {string} id
* @throws {PSVError} if the resolution does not exist
*/
setResolution(id) {
if (!this.resolutionsById[id]) {
throw new PSVError(`Resolution ${id} unknown`);
}
return this.__setResolutionIfExists(id);
}
/**
* @private
* @return {Promise}
*/
__setResolutionIfExists(id) {
if (this.resolutionsById[id]) {
return this.psv.setPanorama(this.resolutionsById[id].panorama, { transition: false, showLoader: false });
}
else {
return Promise.resolve();
}
}
/**
* @summary Returns the current resolution
* @return {string}
*/
getResolution() {
return this.prop.resolution;
}
/**
* @summary Updates current resolution on panorama load
* @private
*/
__refreshResolution() {
const resolution = this.resolutions.find(r => utils.deepEqual(this.psv.config.panorama, r.panorama));
if (this.prop.resolution !== resolution?.id) {
this.prop.resolution = resolution?.id;
this.settings?.updateButton();
this.trigger(EVENTS.RESOLUTION_CHANGED, this.prop.resolution);
}
}
/**
* @summary Returns options for Settings plugin
* @return {PSV.plugins.SettingsPlugin.Option[]}
* @private
*/
__getSettingsOptions() {
return this.resolutions
.map(resolution => ({
id : resolution.id,
label: resolution.label,
}));
}
}