UNPKG

@photo-sphere-viewer/overlays-plugin

Version:

Photo Sphere Viewer plugin to add various overlays over the panorama.

238 lines (234 loc) 7.58 kB
/*! * Photo Sphere Viewer / Overlays Plugin 5.14.0 * @copyright 2015-2025 Damien "Mistic" Sorel * @licence MIT (https://opensource.org/licenses/MIT) */ var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/events.ts var events_exports = {}; __export(events_exports, { OverlayClickEvent: () => OverlayClickEvent }); import { TypedEvent } from "@photo-sphere-viewer/core"; var _OverlayClickEvent = class _OverlayClickEvent extends TypedEvent { /** @internal */ constructor(overlayId) { super(_OverlayClickEvent.type); this.overlayId = overlayId; } }; _OverlayClickEvent.type = "overlay-click"; var OverlayClickEvent = _OverlayClickEvent; // src/OverlaysPlugin.ts import { AbstractConfigurablePlugin, EquirectangularAdapter, PSVError, events, utils } from "@photo-sphere-viewer/core"; // src/constants.ts var OVERLAY_DATA = "psvOverlay"; // src/OverlaysPlugin.ts var getConfig = utils.getConfigParser({ overlays: [], autoclear: true, inheritSphereCorrection: true, cubemapAdapter: null }); var _OverlaysPlugin = class _OverlaysPlugin extends AbstractConfigurablePlugin { constructor(viewer, config) { super(viewer, config); this.state = { overlays: {} }; } static withConfig(config) { return [_OverlaysPlugin, config]; } /** * @internal */ init() { super.init(); this.viewer.addEventListener(events.PanoramaLoadedEvent.type, this, { once: true }); this.viewer.addEventListener(events.PanoramaLoadEvent.type, this); this.viewer.addEventListener(events.ClickEvent.type, this); this.viewer.addEventListener(events.ConfigChangedEvent.type, this); } /** * @internal */ destroy() { this.clearOverlays(); this.viewer.removeEventListener(events.PanoramaLoadedEvent.type, this); this.viewer.removeEventListener(events.PanoramaLoadEvent.type, this); this.viewer.removeEventListener(events.ClickEvent.type, this); this.viewer.removeEventListener(events.ConfigChangedEvent.type, this); delete this.cubemapAdapter; delete this.equirectangularAdapter; super.destroy(); } /** * @internal */ handleEvent(e) { if (e instanceof events.PanoramaLoadedEvent) { this.config.overlays.forEach((overlay) => { this.addOverlay(overlay); }); delete this.config.overlays; } else if (e instanceof events.PanoramaLoadEvent) { if (this.config.autoclear) { this.clearOverlays(); } } else if (e instanceof events.ClickEvent) { if (e.data.rightclick) { return false; } const overlay = e.data.objects.map((o) => o.userData[OVERLAY_DATA]).filter((o) => !!o).map((o) => this.state.overlays[o].config).sort((a, b) => b.zIndex - a.zIndex)[0]; if (overlay) { this.dispatchEvent(new OverlayClickEvent(overlay.id)); } } else if (e instanceof events.ConfigChangedEvent) { if (e.containsOptions("sphereCorrection")) { this.__applySphereCorrection(); } } } /** * Adds a new overlay */ addOverlay(config) { if (!config.path) { throw new PSVError(`Missing overlay "path"`); } const parsedConfig = { id: Math.random().toString(36).substring(2), opacity: 1, zIndex: 0, ...config }; if (this.state.overlays[parsedConfig.id]) { throw new PSVError(`Overlay "${parsedConfig.id} already exists.`); } if (typeof config.path === "string") { this.__addSphereImageOverlay(parsedConfig); } else { this.__addCubeImageOverlay(parsedConfig); } } /** * Removes an overlay */ removeOverlay(id) { if (!this.state.overlays[id]) { utils.logWarn(`Overlay "${id}" not found`); return; } const { mesh } = this.state.overlays[id]; this.viewer.renderer.removeObject(mesh); this.viewer.renderer.cleanScene(mesh); this.viewer.needsUpdate(); delete this.state.overlays[id]; } /** * Remove all overlays */ clearOverlays() { Object.keys(this.state.overlays).forEach((id) => { this.removeOverlay(id); }); } /** * Add a spherical overlay */ async __addSphereImageOverlay(config) { const adapter = this.__getEquirectangularAdapter(); const textureData = await adapter.loadTexture(config.path, false, config.panoData, false); const mesh = adapter.createMesh(textureData.panoData); mesh.renderOrder = 100 + config.zIndex; mesh.userData[OVERLAY_DATA] = config.id; adapter.setTexture(mesh, textureData); adapter.setTextureOpacity(mesh, config.opacity); mesh.material.transparent = true; this.__applySphereCorrection(mesh); this.state.overlays[config.id] = { config, mesh }; this.viewer.renderer.addObject(mesh); this.viewer.needsUpdate(); } /** * Add a cubemap overlay */ async __addCubeImageOverlay(config) { const currentPanoData = this.viewer.state.textureData.panoData; const adapter = this.__getCubemapAdapter(); const textureData = await adapter.loadTexture(config.path, false); if (!("type" in config.path) && currentPanoData.isCubemap) { textureData.panoData.flipTopBottom = currentPanoData.flipTopBottom; } const mesh = adapter.createMesh(); mesh.renderOrder = 100 + config.zIndex; mesh.userData[OVERLAY_DATA] = config.id; adapter.setTexture(mesh, textureData); adapter.setTextureOpacity(mesh, config.opacity); mesh.material.forEach((m) => m.transparent = true); this.__applySphereCorrection(mesh); this.state.overlays[config.id] = { config, mesh }; this.viewer.renderer.addObject(mesh); this.viewer.needsUpdate(); } __applySphereCorrection(mesh) { if (this.config.inheritSphereCorrection) { if (mesh) { this.viewer.renderer.setSphereCorrection(this.viewer.config.sphereCorrection, mesh); } else { Object.values(this.state.overlays).forEach(({ mesh: mesh2 }) => { this.viewer.renderer.setSphereCorrection(this.viewer.config.sphereCorrection, mesh2); }); } } } __getEquirectangularAdapter() { if (!this.equirectangularAdapter) { const id = this.viewer.adapter.constructor.id; if (id === "equirectangular") { this.equirectangularAdapter = this.viewer.adapter; } else if (id === "equirectangular-tiles") { this.equirectangularAdapter = this.viewer.adapter.adapter; } else { this.equirectangularAdapter = new EquirectangularAdapter(this.viewer); } } return this.equirectangularAdapter; } __getCubemapAdapter() { if (!this.cubemapAdapter) { const id = this.viewer.adapter.constructor.id; if (id === "cubemap") { this.cubemapAdapter = this.viewer.adapter; } else if (id === "cubemap-tiles") { this.cubemapAdapter = this.viewer.adapter.adapter; } else if (this.config.cubemapAdapter) { this.cubemapAdapter = new this.config.cubemapAdapter(this.viewer); } else { throw new PSVError(`Cubemap overlays are only applicable with cubemap adapters`); } } return this.cubemapAdapter; } }; _OverlaysPlugin.id = "overlays"; _OverlaysPlugin.VERSION = "5.14.0"; _OverlaysPlugin.configParser = getConfig; _OverlaysPlugin.readonlyOptions = ["overlays", "cubemapAdapter", "inheritSphereCorrection"]; var OverlaysPlugin = _OverlaysPlugin; export { OverlaysPlugin, events_exports as events }; //# sourceMappingURL=index.module.js.map