@photo-sphere-viewer/markers-plugin
Version:
Photo Sphere Viewer plugin to display various markers/hotspots on the viewer.
620 lines (612 loc) • 19.4 kB
text/typescript
import { Position, Point, Size, SphericalPosition, PanoramaPosition, ExtendedPosition, AbstractConfigurablePlugin, utils, PluginConstructor, Viewer, TypedEvent } from '@photo-sphere-viewer/core';
import { ColorRepresentation, Object3D } from 'three';
/**
* Custom Web Component interface for `element` markers
* @noInheritDoc
*/
interface MarkerElement extends HTMLElement {
updateMarker?(params: {
marker: Marker;
position: Point;
viewerPosition: Position;
zoomLevel: number;
viewerSize: Size;
}): void;
}
/**
* Configuration of a marker
*/
type MarkerConfig = {
/**
* Path to an image
*/
image?: string;
/**
* Path to an image
*/
imageLayer?: string;
/**
* Path to a video
*/
videoLayer?: string;
/**
* HTML content of the marker
*/
html?: string;
/**
* Exiting DOM element
*/
element?: MarkerElement;
/**
* Exiting DOM element
*/
elementLayer?: MarkerElement;
/**
* Size of the square
*/
square?: number;
/**
* Size of the rectangle
*/
rect?: [number, number] | {
width: number;
height: number;
};
/**
* Radius of the circle
*/
circle?: number;
/**
* Radiuses of the ellipse
*/
ellipse?: [number, number] | {
rx: number;
ry: number;
};
/**
* Definition of the path
*/
path?: string;
/**
* Array of points defining the polygon in spherical coordinates
* Nested arrays are used to define holes
*/
polygon?: Array<[number, number]> | Array<Array<[number, number]>> | Array<[string, string]> | Array<Array<[string, string]>> | SphericalPosition[] | SphericalPosition[][];
/**
* Array of points defining the polygon in pixel coordinates on the panorama image
* Nested arrays are used to define holes
*/
polygonPixels?: Array<[number, number]> | Array<Array<[number, number]>> | PanoramaPosition[] | PanoramaPosition[][];
/**
* Array of points defining the polyline in spherical coordinates
*/
polyline?: Array<[number, number]> | Array<[string, string]> | SphericalPosition[];
/**
* Array of points defining the polyline in pixel coordinates on the panorama image
*/
polylinePixels?: Array<[number, number]> | PanoramaPosition[];
/**
* Unique identifier of the marker
*/
id: string;
/**
* Position of the marker (required but for `polygon` and `polyline`)
* The array form is used for `imageLayer` and `videoLayer`
*/
position?: ExtendedPosition | [ExtendedPosition, ExtendedPosition, ExtendedPosition, ExtendedPosition];
/**
* Size of the marker (required for `image`, recommended for `html`, ignored for others)
*/
size?: Size;
/**
* Rotation applied to the marker (ignored for `polygon` and `polyline`)
* If defined as a scalar, it applies to the `roll` (Z axis)
* Only 3D markers (`imageLayer`, `videoLayer`, `elementLayer`) support `yaw` and `pitch`
*/
rotation?: string | number | {
yaw?: number | string;
pitch?: number | string;
roll?: number | string;
};
/**
* Configures the scale of the marker depending on the zoom level and/or the horizontal offset (ignored for `polygon`, `polyline`, `imageLayer`, `videoLayer`)
*/
scale?: [number, number] | {
zoom?: [number, number];
yaw?: [number, number];
} | ((zoomLevel: number, position: Position) => number);
/**
* Overrides the global `defaultHoverScale`
* @default null
*/
hoverScale?: boolean | number | {
amount?: number;
duration?: number;
easing?: string;
};
/**
* Opacity of the marker
* @default 1
*/
opacity?: number;
/**
* Drawing order
* @default 1
*/
zIndex?: number;
/**
* CSS class(es) added to the marker element (ignored for `imageLayer`, `videoLayer`)
*/
className?: string;
/**
* CSS properties to set on the marker (background, border, etc.) (ignored for `imagerLayer`, `videoLayer`)
*/
style?: Record<string, string>;
/**
* SVG properties to set on the marker (fill, stroke, etc.) (only for SVG markers)
*/
svgStyle?: Record<string, string>;
/**
* Will make a color of the image/video transparent (only for `imagerLayer`, `videoLayer`)
*/
chromaKey?: {
/** @default false */
enabled: boolean;
/** @default 0x00ff00 */
color?: ColorRepresentation | {
r: number;
g: number;
b: number;
};
/** @default 0.2 */
similarity?: number;
/** @default 0.2 */
smoothness?: number;
};
/**
* Defines where the marker is placed toward its defined position
* @default 'center center'
*/
anchor?: string;
/**
* The zoom level which will be applied when calling `gotoMarker()` method or when clicking on the marker in the list
* @default `current zoom level`
*/
zoomLvl?: number;
/**
* Initial visibility of the marker
* @default true
*/
visible?: boolean;
/**
* Configuration of the marker tooltip
* @default `{content: null, position: 'top center', className: null, trigger: 'hover'}`
*/
tooltip?: string | {
content: string;
position?: string;
className?: string;
trigger?: 'hover' | 'click';
};
/**
* HTML content that will be displayed on the side panel when the marker is clicked
*/
content?: string;
/**
* The name that appears in the list of markers
* @default `tooltip.content`
*/
listContent?: string;
/**
* Hide the marker in the markers list
* @default false
*/
hideList?: boolean;
/**
* Autoplay of `videoLayer` markers
* @default true
*/
autoplay?: boolean;
/**
* Any custom data you want to attach to the marker
*/
data?: any;
};
type ParsedMarkerConfig = Omit<MarkerConfig, 'rotation' | 'scale' | 'tooltip' | 'hoverScale'> & {
rotation?: {
yaw?: number;
pitch?: number;
roll?: number;
};
scale?: {
zoom?: [number, number];
yaw?: [number, number];
} | ((zoomLevel: number, position: Position) => number);
tooltip?: {
content: string;
position?: string;
className?: string;
trigger?: 'hover' | 'click';
};
hoverScale?: {
amount: number;
duration: number;
easing: string;
};
};
type MarkersPluginConfig = {
/**
* If a `click` event is triggered on the viewer additionally to the `select-marker` event
* @default false
*/
clickEventOnMarker?: boolean;
/**
* initial markers
*/
markers?: MarkerConfig[];
/**
* Default animation speed for {@link MarkersPlugin#gotoMarker} and when a marker in clicked in the list/map
* @default '8rpm'
*/
gotoMarkerSpeed?: string | number;
/**
* Default mouse hover scaling parameters applied to all markers
* (`true` = `{ amount: 2, duration: 100, easing: 'linear' }`)
* @default null
*/
defaultHoverScale?: boolean | number | {
amount?: number;
duration?: number;
easing?: string;
};
};
type ParsedMarkersPluginConfig = Omit<MarkersPluginConfig, 'defaultHoverScale'> & {
defaultHoverScale?: {
amount: number;
duration: number;
easing: string;
};
};
type UpdatableMarkersPluginConfig = Omit<MarkersPluginConfig, 'markers'>;
declare enum MarkerType {
image = "image",
html = "html",
element = "element",
imageLayer = "imageLayer",
videoLayer = "videoLayer",
elementLayer = "elementLayer",
polygon = "polygon",
polygonPixels = "polygonPixels",
polyline = "polyline",
polylinePixels = "polylinePixels",
square = "square",
rect = "rect",
circle = "circle",
ellipse = "ellipse",
path = "path"
}
/**
* Displays various markers on the viewer
*/
declare class MarkersPlugin extends AbstractConfigurablePlugin<MarkersPluginConfig, ParsedMarkersPluginConfig, UpdatableMarkersPluginConfig, MarkersPluginEvents> {
static readonly id = "markers";
static readonly VERSION: string;
static readonly configParser: utils.ConfigParser<MarkersPluginConfig, ParsedMarkersPluginConfig>;
static readonly readonlyOptions: Array<keyof MarkersPluginConfig>;
private readonly markers;
private readonly state;
private readonly container;
private readonly svgContainer;
private readonly css3DContainer;
static withConfig(config: MarkersPluginConfig): [PluginConstructor, any];
constructor(viewer: Viewer, config: MarkersPluginConfig);
/**
* Toggles all markers
*/
toggleAllMarkers(): void;
/**
* Shows all markers
*/
showAllMarkers(): void;
/**
* Hides all markers
*/
hideAllMarkers(): void;
/**
* Toggles the visibility of all tooltips
*/
toggleAllTooltips(): void;
/**
* Displays all tooltips
*/
showAllTooltips(): void;
/**
* Hides all tooltips
*/
hideAllTooltips(): void;
/**
* Returns the total number of markers
*/
getNbMarkers(): number;
/**
* Returns all the markers
*/
getMarkers(): Marker[];
/**
* Adds a new marker to viewer
* @throws {@link PSVError} when the marker's id is missing or already exists
*/
addMarker(config: MarkerConfig, render?: boolean): void;
/**
* Returns the internal marker object for a marker id
* @throws {@link PSVError} when the marker cannot be found
*/
getMarker(markerId: string | MarkerConfig): Marker;
/**
* Returns the last marker selected by the user
*/
getCurrentMarker(): Marker;
/**
* Updates the existing marker with the same id
* Every property can be changed but you can't change its type (Eg: `image` to `html`)
*/
updateMarker(config: MarkerConfig, render?: boolean): void;
/**
* Removes a marker from the viewer
*/
removeMarker(markerId: string | MarkerConfig, render?: boolean): void;
/**
* Removes multiple markers
*/
removeMarkers(markerIds: string[], render?: boolean): void;
/**
* Replaces all markers
*/
setMarkers(markers: MarkerConfig[] | null, render?: boolean): void;
/**
* Removes all markers
*/
clearMarkers(render?: boolean): void;
/**
* Rotate the view to face the marker
*/
gotoMarker(markerId: string | MarkerConfig, speed?: string | number): Promise<void>;
/**
* Hides a marker
*/
hideMarker(markerId: string | MarkerConfig): void;
/**
* Shows a marker
*/
showMarker(markerId: string | MarkerConfig): void;
/**
* Forces the display of the tooltip of a marker
*/
showMarkerTooltip(markerId: string | MarkerConfig): void;
/**
* Hides the tooltip of a marker
*/
hideMarkerTooltip(markerId: string | MarkerConfig): void;
/**
* Toggles a marker visibility
*/
toggleMarker(markerId: string | MarkerConfig, visible?: boolean): void;
/**
* Opens the panel with the content of the marker
*/
showMarkerPanel(markerId: string | MarkerConfig): void;
/**
* Closes the panel if currently showing the content of a marker
*/
hideMarkerPanel(): void;
/**
* Toggles the visibility of the list of markers
*/
toggleMarkersList(): void;
/**
* Opens side panel with the list of markers
*/
showMarkersList(): void;
/**
* Closes side panel if it contains the list of markers
*/
hideMarkersList(): void;
/**
* Updates the visibility and the position of all markers
*/
renderMarkers(): void;
/**
* Returns the marker associated to an event target
*/
private __getTargetMarker;
/**
* Handles mouse enter events, show the tooltip for non polygon markers
*/
private __onEnterMarker;
/**
* Handles mouse leave events, hide the tooltip
*/
private __onLeaveMarker;
/**
* Handles mouse move events, refresh the tooltip for polygon markers
*/
private __onHoverMarker;
/**
* Handles mouse click events, select the marker and open the panel if necessary
*/
private __onClick;
private __afterChangeMarkers;
/**
* Updates the visiblity of the panel and the buttons
*/
private __refreshUi;
/**
* Adds or remove the objects observer if there are 3D markers
*/
private __checkObjectsObserver;
}
/**
* Base class for all markers
*/
declare abstract class Marker {
protected viewer: Viewer;
protected plugin: MarkersPlugin;
readonly type: MarkerType;
protected element: any;
/**
* The final description of the marker. Either text content, image, url, SVG attributes, etc.
*/
definition: any;
config: ParsedMarkerConfig;
get id(): string;
get data(): any;
get domElement(): HTMLElement | SVGElement;
get threeElement(): Object3D;
get video(): HTMLVideoElement;
constructor(viewer: Viewer, plugin: MarkersPlugin, config: MarkerConfig);
/**
* Checks if it is a 3D marker (imageLayer, videoLayer)
*/
is3d(): boolean;
/**
* Checks if it is a normal marker (image, html, element)
*/
isNormal(): boolean;
/**
* Checks if it is a polygon/polyline marker
*/
isPoly(): boolean;
/**
* Checks if it is an SVG marker
*/
isSvg(): boolean;
/**
* Checks if it is an CSS3D marker
*/
isCss3d(): boolean;
}
/**
* Base class for events dispatched by {@link MarkersPlugin}
*/
declare abstract class MarkersPluginEvent extends TypedEvent<MarkersPlugin> {
}
/**
* @event Triggered when the visibility of a marker changes
*/
declare class MarkerVisibilityEvent extends MarkersPluginEvent {
readonly marker: Marker;
readonly visible: boolean;
static readonly type = "marker-visibility";
type: 'marker-visibility';
}
/**
* @event Triggered when the animation to a marker is done
*/
declare class GotoMarkerDoneEvent extends MarkersPluginEvent {
readonly marker: Marker;
static readonly type = "goto-marker-done";
type: 'goto-marker-done';
}
/**
* @event Triggered when the user puts the cursor away from a marker
*/
declare class LeaveMarkerEvent extends MarkersPluginEvent {
readonly marker: Marker;
static readonly type = "leave-marker";
type: 'leave-marker';
}
/**
* @event Triggered when the user puts the cursor hover a marker
*/
declare class EnterMarkerEvent extends MarkersPluginEvent {
readonly marker: Marker;
static readonly type = "enter-marker";
type: 'enter-marker';
}
/**
* @event Triggered when the user clicks on a marker
*/
declare class SelectMarkerEvent extends MarkersPluginEvent {
readonly marker: Marker;
readonly doubleClick: boolean;
readonly rightClick: boolean;
static readonly type = "select-marker";
type: 'select-marker';
}
/**
* @event Triggered when a marker is selected from the side panel
*/
declare class SelectMarkerListEvent extends MarkersPluginEvent {
readonly marker: Marker;
static readonly type = "select-marker-list";
type: 'select-marker-list';
}
/**
* @event Triggered when a marker was selected and the user clicks elsewhere
*/
declare class UnselectMarkerEvent extends MarkersPluginEvent {
readonly marker: Marker;
static readonly type = "unselect-marker";
type: 'unselect-marker';
}
/**
* @event Triggered when the markers are hidden
*/
declare class HideMarkersEvent extends MarkersPluginEvent {
static readonly type = "hide-markers";
type: 'hide-markers';
}
/**
* @event Triggered when the markers change
*/
declare class SetMarkersEvent extends MarkersPluginEvent {
readonly markers: Marker[];
static readonly type = "set-markers";
type: 'set-markers';
}
/**
* @event Triggered when the markers are shown
*/
declare class ShowMarkersEvent extends MarkersPluginEvent {
static readonly type = "show-markers";
type: 'show-markers';
}
/**
* @event Used to alter the list of markers displayed in the side-panel
*/
declare class RenderMarkersListEvent extends MarkersPluginEvent {
/** the list of markers to display, can be modified */
markers: Marker[];
static readonly type = "render-markers-list";
type: 'render-markers-list';
}
type MarkersPluginEvents = MarkerVisibilityEvent | GotoMarkerDoneEvent | LeaveMarkerEvent | EnterMarkerEvent | SelectMarkerEvent | SelectMarkerListEvent | UnselectMarkerEvent | HideMarkersEvent | SetMarkersEvent | ShowMarkersEvent | RenderMarkersListEvent;
type events_EnterMarkerEvent = EnterMarkerEvent;
declare const events_EnterMarkerEvent: typeof EnterMarkerEvent;
type events_GotoMarkerDoneEvent = GotoMarkerDoneEvent;
declare const events_GotoMarkerDoneEvent: typeof GotoMarkerDoneEvent;
type events_HideMarkersEvent = HideMarkersEvent;
declare const events_HideMarkersEvent: typeof HideMarkersEvent;
type events_LeaveMarkerEvent = LeaveMarkerEvent;
declare const events_LeaveMarkerEvent: typeof LeaveMarkerEvent;
type events_MarkerVisibilityEvent = MarkerVisibilityEvent;
declare const events_MarkerVisibilityEvent: typeof MarkerVisibilityEvent;
type events_MarkersPluginEvent = MarkersPluginEvent;
declare const events_MarkersPluginEvent: typeof MarkersPluginEvent;
type events_MarkersPluginEvents = MarkersPluginEvents;
type events_RenderMarkersListEvent = RenderMarkersListEvent;
declare const events_RenderMarkersListEvent: typeof RenderMarkersListEvent;
type events_SelectMarkerEvent = SelectMarkerEvent;
declare const events_SelectMarkerEvent: typeof SelectMarkerEvent;
type events_SelectMarkerListEvent = SelectMarkerListEvent;
declare const events_SelectMarkerListEvent: typeof SelectMarkerListEvent;
type events_SetMarkersEvent = SetMarkersEvent;
declare const events_SetMarkersEvent: typeof SetMarkersEvent;
type events_ShowMarkersEvent = ShowMarkersEvent;
declare const events_ShowMarkersEvent: typeof ShowMarkersEvent;
type events_UnselectMarkerEvent = UnselectMarkerEvent;
declare const events_UnselectMarkerEvent: typeof UnselectMarkerEvent;
declare namespace events {
export { events_EnterMarkerEvent as EnterMarkerEvent, events_GotoMarkerDoneEvent as GotoMarkerDoneEvent, events_HideMarkersEvent as HideMarkersEvent, events_LeaveMarkerEvent as LeaveMarkerEvent, events_MarkerVisibilityEvent as MarkerVisibilityEvent, events_MarkersPluginEvent as MarkersPluginEvent, type events_MarkersPluginEvents as MarkersPluginEvents, events_RenderMarkersListEvent as RenderMarkersListEvent, events_SelectMarkerEvent as SelectMarkerEvent, events_SelectMarkerListEvent as SelectMarkerListEvent, events_SetMarkersEvent as SetMarkersEvent, events_ShowMarkersEvent as ShowMarkersEvent, events_UnselectMarkerEvent as UnselectMarkerEvent };
}
export { Marker, type MarkerConfig, type MarkerElement, MarkerType, MarkersPlugin, type MarkersPluginConfig, type ParsedMarkerConfig, type ParsedMarkersPluginConfig, type UpdatableMarkersPluginConfig, events };