UNPKG

@photo-sphere-viewer/overlays-plugin

Version:

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

1 lines 14.9 kB
{"version":3,"sources":["src/index.ts","src/events.ts","src/OverlaysPlugin.ts","src/constants.ts"],"sourcesContent":["import * as events from './events';\n\nexport { OverlaysPlugin } from './OverlaysPlugin';\nexport * from './model';\nexport { events };\n","import { TypedEvent } from '@photo-sphere-viewer/core';\nimport type { OverlaysPlugin } from './OverlaysPlugin';\n\n/**\n * @event Triggered when an overlay is clicked\n */\nexport class OverlayClickEvent extends TypedEvent<OverlaysPlugin> {\n static override readonly type = 'overlay-click';\n override type: 'overlay-click';\n\n /** @internal */\n constructor(public readonly overlayId: string) {\n super(OverlayClickEvent.type);\n }\n}\n\nexport type OverlaysPluginEvents = OverlayClickEvent;\n","import type { AbstractAdapter, PluginConstructor, Viewer } from '@photo-sphere-viewer/core';\nimport {\n AbstractConfigurablePlugin,\n EquirectangularAdapter,\n PSVError,\n events,\n utils,\n} from '@photo-sphere-viewer/core';\nimport type { CubemapAdapter, CubemapData } from '@photo-sphere-viewer/cubemap-adapter';\nimport type { CubemapTilesAdapter } from '@photo-sphere-viewer/cubemap-tiles-adapter';\nimport type { EquirectangularTilesAdapter } from '@photo-sphere-viewer/equirectangular-tiles-adapter';\nimport { Mesh } from 'three';\nimport { OVERLAY_DATA } from './constants';\nimport { OverlayClickEvent, OverlaysPluginEvents } from './events';\nimport {\n CubeOverlayConfig,\n OverlayConfig,\n OverlaysPluginConfig,\n SphereOverlayConfig,\n UpdatableOverlaysPluginConfig,\n} from './model';\n\nconst getConfig = utils.getConfigParser<OverlaysPluginConfig>({\n overlays: [],\n autoclear: true,\n inheritSphereCorrection: true,\n cubemapAdapter: null,\n});\n\n/**\n * Adds various overlays over the panorama\n */\nexport class OverlaysPlugin extends AbstractConfigurablePlugin<\n OverlaysPluginConfig,\n OverlaysPluginConfig,\n UpdatableOverlaysPluginConfig,\n OverlaysPluginEvents\n> {\n static override readonly id = 'overlays';\n static override readonly VERSION = PKG_VERSION;\n static override configParser = getConfig;\n static override readonlyOptions: Array<keyof OverlaysPluginConfig> = ['overlays', 'cubemapAdapter', 'inheritSphereCorrection'];\n\n private readonly state = {\n overlays: {} as Record<string, { config: OverlayConfig; mesh: Mesh }>,\n };\n\n private cubemapAdapter: CubemapAdapter;\n private equirectangularAdapter: EquirectangularAdapter;\n\n static withConfig(config: OverlaysPluginConfig): [PluginConstructor, any] {\n return [OverlaysPlugin, config];\n }\n\n constructor(viewer: Viewer, config?: OverlaysPluginConfig) {\n super(viewer, config);\n }\n\n /**\n * @internal\n */\n override init() {\n super.init();\n\n this.viewer.addEventListener(events.PanoramaLoadedEvent.type, this, { once: true });\n this.viewer.addEventListener(events.PanoramaLoadEvent.type, this);\n this.viewer.addEventListener(events.ClickEvent.type, this);\n this.viewer.addEventListener(events.ConfigChangedEvent.type, this);\n }\n\n /**\n * @internal\n */\n override destroy() {\n this.clearOverlays();\n\n this.viewer.removeEventListener(events.PanoramaLoadedEvent.type, this);\n this.viewer.removeEventListener(events.PanoramaLoadEvent.type, this);\n this.viewer.removeEventListener(events.ClickEvent.type, this);\n this.viewer.removeEventListener(events.ConfigChangedEvent.type, this);\n\n delete this.cubemapAdapter;\n delete this.equirectangularAdapter;\n\n super.destroy();\n }\n\n /**\n * @internal\n */\n handleEvent(e: Event) {\n if (e instanceof events.PanoramaLoadedEvent) {\n this.config.overlays.forEach((overlay) => {\n this.addOverlay(overlay);\n });\n delete this.config.overlays;\n } else if (e instanceof events.PanoramaLoadEvent) {\n if (this.config.autoclear) {\n this.clearOverlays();\n }\n } else if (e instanceof events.ClickEvent) {\n if (e.data.rightclick) {\n return false;\n }\n const overlay = e.data.objects\n .map(o => o.userData[OVERLAY_DATA] as OverlayConfig['id'])\n .filter(o => !!o)\n .map(o => this.state.overlays[o].config)\n .sort((a, b) => b.zIndex - a.zIndex)[0];\n\n if (overlay) {\n this.dispatchEvent(new OverlayClickEvent(overlay.id));\n }\n } else if (e instanceof events.ConfigChangedEvent) {\n if (e.containsOptions('sphereCorrection')) {\n this.__applySphereCorrection();\n }\n }\n }\n\n /**\n * Adds a new overlay\n */\n addOverlay(config: OverlayConfig) {\n if (!config.path) {\n throw new PSVError(`Missing overlay \"path\"`);\n }\n\n const parsedConfig: OverlayConfig = {\n id: Math.random().toString(36).substring(2),\n opacity: 1,\n zIndex: 0,\n ...config,\n };\n\n if (this.state.overlays[parsedConfig.id]) {\n throw new PSVError(`Overlay \"${parsedConfig.id} already exists.`);\n }\n\n if (typeof config.path === 'string') {\n this.__addSphereImageOverlay(parsedConfig as any);\n } else {\n this.__addCubeImageOverlay(parsedConfig as any);\n }\n }\n\n /**\n * Removes an overlay\n */\n removeOverlay(id: string) {\n if (!this.state.overlays[id]) {\n utils.logWarn(`Overlay \"${id}\" not found`);\n return;\n }\n\n const { mesh } = this.state.overlays[id];\n\n this.viewer.renderer.removeObject(mesh);\n this.viewer.renderer.cleanScene(mesh);\n this.viewer.needsUpdate();\n\n delete this.state.overlays[id];\n }\n\n /**\n * Remove all overlays\n */\n clearOverlays() {\n Object.keys(this.state.overlays).forEach((id) => {\n this.removeOverlay(id);\n });\n }\n\n /**\n * Add a spherical overlay\n */\n private async __addSphereImageOverlay(config: SphereOverlayConfig) {\n const adapter = this.__getEquirectangularAdapter();\n\n const textureData = await adapter.loadTexture(config.path, false, config.panoData, false);\n\n const mesh = adapter.createMesh(textureData.panoData);\n mesh.renderOrder = 100 + config.zIndex;\n mesh.userData[OVERLAY_DATA] = config.id;\n\n adapter.setTexture(mesh, textureData);\n adapter.setTextureOpacity(mesh, config.opacity);\n mesh.material.transparent = true;\n this.__applySphereCorrection(mesh);\n\n this.state.overlays[config.id] = { config, mesh };\n\n this.viewer.renderer.addObject(mesh);\n this.viewer.needsUpdate();\n }\n\n /**\n * Add a cubemap overlay\n */\n private async __addCubeImageOverlay(config: CubeOverlayConfig) {\n const currentPanoData = this.viewer.state.textureData.panoData as CubemapData;\n\n const adapter = this.__getCubemapAdapter();\n\n const textureData = await adapter.loadTexture(config.path, false);\n\n if (!('type' in config.path) && currentPanoData.isCubemap) {\n textureData.panoData.flipTopBottom = currentPanoData.flipTopBottom;\n }\n\n const mesh = adapter.createMesh();\n mesh.renderOrder = 100 + config.zIndex;\n mesh.userData[OVERLAY_DATA] = config.id;\n\n adapter.setTexture(mesh, textureData);\n adapter.setTextureOpacity(mesh, config.opacity);\n mesh.material.forEach(m => m.transparent = true);\n this.__applySphereCorrection(mesh);\n\n this.state.overlays[config.id] = { config, mesh };\n\n this.viewer.renderer.addObject(mesh);\n this.viewer.needsUpdate();\n }\n\n private __applySphereCorrection(mesh?: Mesh) {\n if (this.config.inheritSphereCorrection) {\n if (mesh) {\n this.viewer.renderer.setSphereCorrection(this.viewer.config.sphereCorrection, mesh);\n } else {\n Object.values(this.state.overlays).forEach(({ mesh }) => {\n this.viewer.renderer.setSphereCorrection(this.viewer.config.sphereCorrection, mesh);\n });\n }\n }\n }\n\n private __getEquirectangularAdapter() {\n if (!this.equirectangularAdapter) {\n const id = (this.viewer.adapter.constructor as typeof AbstractAdapter).id;\n if (id === 'equirectangular') {\n this.equirectangularAdapter = this.viewer.adapter as EquirectangularAdapter;\n } else if (id === 'equirectangular-tiles') {\n this.equirectangularAdapter = (this.viewer.adapter as EquirectangularTilesAdapter).adapter;\n } else {\n this.equirectangularAdapter = new EquirectangularAdapter(this.viewer);\n }\n }\n\n return this.equirectangularAdapter;\n }\n\n private __getCubemapAdapter() {\n if (!this.cubemapAdapter) {\n const id = (this.viewer.adapter.constructor as typeof AbstractAdapter).id;\n if (id === 'cubemap') {\n this.cubemapAdapter = this.viewer.adapter as CubemapAdapter;\n } else if (id === 'cubemap-tiles') {\n this.cubemapAdapter = (this.viewer.adapter as CubemapTilesAdapter).adapter;\n } else if (this.config.cubemapAdapter) {\n this.cubemapAdapter = new this.config.cubemapAdapter(this.viewer) as CubemapAdapter;\n } else {\n throw new PSVError(`Cubemap overlays are only applicable with cubemap adapters`);\n }\n }\n\n return this.cubemapAdapter;\n }\n}\n","export const OVERLAY_DATA = 'psvOverlay';\n"],"mappings":"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","names":["import_core","mesh"]}