@seatmap.pro/renderer
Version:
Seatmap renderer library for booking and admin interfaces by Seatmap.pro
1,993 lines (1,982 loc) • 64.1 kB
TypeScript
import KDBush from 'kdbush';
import { Machine, Service } from 'robot3';
/**
* Base interface for seat properties.
*/
interface IBaseSeat {
/**
* The unique identifier of the seat.
*/
id: number;
/**
* The ID of the row this seat belongs to.
*/
rowId: number;
/**
* The ID of the sector this seat belongs to.
*/
sectorId: number;
/**
* The X coordinate of the seat within its section.
*/
x: number;
/**
* The Y coordinate of the seat within its section.
*/
y: number;
/**
* The name or number of the seat.
*/
name: string;
/**
* Whether the seat is accessible for people with disabilities.
*/
isAccessible?: boolean;
/**
* Whether the seat is marked with a special status.
*/
isMarked?: boolean;
}
/**
* Base interface for sector properties.
*/
interface IBaseSector {
/**
* The unique identifier of the sector.
*/
id: number;
/**
* The globally unique identifier for the sector.
*/
guid?: string;
/**
* Whether this is a general admission (GA) sector.
*/
isGa: boolean;
/**
* The name of the sector.
*/
name: string;
/**
* The rotation angle of the sector in degrees.
*/
angle?: number | null;
/**
* The type of the sector.
*/
type?: string | null;
/**
* Whether the sector is disabled and cannot be interacted with.
*/
disabled?: boolean;
/**
* Whether the sector is filtered out by current filter criteria.
*/
filtered?: boolean;
/**
* Whether the sector is currently selected.
*/
selected?: boolean;
}
/**
* Interface representing the schema data transfer object from the API.
* @hidden
*/
interface ISchemaDTO {
plainSeats?: IPlainSeatsDTO;
seats: ISeatDTO[];
rows: IRowDTO[];
sectors: ISectorDTO[];
background: ISVGBackgroundDTO;
requestTime?: number;
responseSize?: number;
configuration?: IConfigurationDTO;
}
/**
* Interface representing the venue data transfer object from the API.
* @hidden
*/
interface IVenueDTO {
guid: string;
name: string;
gaCapacity?: number;
seatsCapacity?: number;
seatmap: ISchemaDTO;
schema: ISchemaDTO;
}
/**
* Interface representing the plain seats data transfer object from the API.
* @hidden
*/
interface IPlainSeatsDTO {
ids: number[];
x: number[];
y: number[];
rowIds: [];
sectorIds: [];
names: string[];
}
/**
* Interface representing the base seat data transfer object from the API.
* Contains the core properties of a seat as received from the backend.
* @hidden
*/
interface ISeatDTO extends IBaseSeat {
}
/**
* Interface representing a row in the venue.
* @hidden
*/
interface IRowDTO {
id: number;
rowNumber: number;
sectorId: number;
name: string;
seatName: string;
}
/**
* Interface representing the base sector data transfer object from the API.
* Contains the core properties of a sector as received from the backend.
* @hidden
*/
interface ISectorDTO extends IBaseSector {
}
/**
* Interface representing the SVG background data transfer object from the API.
* @hidden
*/
interface ISVGBackgroundDTO {
svg?: Nullable<string>;
viewBox: {
x: number;
y: number;
width: number;
height: number;
};
svgLink?: string;
images?: IPngBackgroundDTO;
outlineSvg?: Nullable<string>;
}
/**
* Interface representing the configuration data transfer object from the API.
* @hidden
*/
interface IConfigurationDTO {
accessible: number[];
marked: number[];
eventName?: string;
}
/**
* Interface representing a special price option for seats, sections, or sectors.
* Contains information about a named price point with its identifier.
*/
interface ISpecialPrice {
/**
* The name or label of the special price option.
*/
name: string;
/**
* The unique identifier for this price option.
*/
priceId: number;
}
/**
* Interface representing special state information for seats, sections, or sectors.
* Contains additional properties that affect rendering or behavior.
*/
interface ISpecialState {
/**
* Special state flag 1, used for custom state indicators.
*/
s1?: number;
/**
* Array of special prices associated with this item.
*/
prices?: ISpecialPrice[];
/**
* Category identifier for grouping items with similar special states.
*/
category?: number;
}
/**
* Interface representing a price list data transfer object from the API.
* @hidden
*/
interface IPriceListDTO {
seats: [number, IPriceId, ISpecialState?][];
groupOfSeats: [number, number, number, ISpecialState?][];
prices: IPriceDTO[];
requestTime?: number;
responseSize?: number;
}
/**
* Interface representing a price data transfer object from the API.
* @hidden
*/
interface IPriceDTO {
id: IPriceId;
name: string;
}
/**
* Type representing blurred image data.
* @hidden
*/
type IBlurred = {
data: string;
shrink_factor: number;
size: number;
status: string;
};
/**
* Type representing a PNG image loaded from a URL.
* @hidden
*/
type IPngFromUrl = {
height: number;
size: number;
width: number;
path: string;
status: string;
};
/**
* Interface representing PNG background images in different resolutions.
* @hidden
*/
interface IPngBackgroundDTO {
blurred: IBlurred;
preview: IPngFromUrl;
full: IPngFromUrl;
}
/**
* Settings for the BookingApiClient.
* @hidden
*/
interface IBookingApiClientSettings {
baseUrl: string;
publicKey: string;
debug?: boolean;
}
/**
* Metrics for API requests.
* @hidden
*/
interface RequestMetrics {
data?: string;
requestTime: number;
responseSize: number;
}
/**
* API client for fetching schema and price data from the booking API.
* @hidden
*/
declare class BookingApiClient {
private settings;
constructor(settings: IBookingApiClientSettings);
/**
* Returns schema data
* @param schemaId Schema ID
*/
fetchSchema(schemaId: number): Promise<ISchemaDTO>;
/**
* Returns schema data
* @param venueId Venue GUID
*/
fetchSchemaForVenue(venueId: string): Promise<Omit<IVenueDTO, 'seatmap'>>;
/**
* Returns schema data
* @param eventId Event GUID
*/
fetchSchemaForEvent(eventId: string): Promise<ISchemaDTO>;
private unpackSchemaDTO;
/**
* Return prices information
* @param eventId Event GUID
*/
fetchPricesForEvent(eventId: string): Promise<IPriceListDTO>;
/**
* Return rows SVG information
* @param eventId Event GUID
*/
fetchRowsSvgForEvent(eventId: string): Promise<RequestMetrics>;
/**
* Makes request to booking API
* @param url Relative API endpoint URL, e.g. 'event/prices/?id=XXX'
*/
request<T>(url: string): Promise<T>;
/**
* Makes request to booking API
* @param url Relative API endpoint URL, e.g. 'event/prices/?id=XXX'
*/
requestPlain<T extends RequestMetrics>(url: string): Promise<T>;
private restoreSeats;
private restoreIds;
}
interface IPoint {
readonly x: number;
readonly y: number;
}
type ById$1<T> = {
[id: number]: T;
};
interface IPrice {
id: IPriceId;
name: string;
}
interface IColoredPrice extends IPrice {
color: string;
}
/**
* @hidden
*/
type ColorSequenceSettings = string[][];
/**
* @hidden
*/
declare const sortPrices: <T extends IPrice>(prices: T[]) => T[];
/**
* @hidden
*/
declare const convertPricesToColored: (prices: IPrice[], colorSettings: ColorSequenceSettings) => IColoredPrice[];
/**
* @hidden
*/
declare const convertPricesToColoredById: (prices: IPrice[], colorSettings: ColorSequenceSettings) => ById$1<IColoredPrice>;
interface IVisibilityStatus {
selectable: boolean;
visible: boolean;
}
interface IVisibilityStatuses {
outline: IVisibilityStatus;
seat: IVisibilityStatus;
}
/**
* @hidden
*/
interface IRendererMachineContext {
mode?: string;
scale: number;
isEagleView: boolean;
events: DestEvent[];
hovered?: {
targetType: RendererTargetType;
id: number;
};
visibility?: IVisibilityStatuses;
}
/**
* @hidden
*/
type RendererMachineReducer<T> = (ctx: IRendererMachineContext, src: T) => IRendererMachineContext;
/**
* @hidden
*/
type RendererMachine = Machine<any, IRendererMachineContext, any>;
/**
* @hidden
*/
type RendererMachineService = Service<RendererMachine>;
/**
* @hidden
*/
declare enum RendererTargetType {
SEAT = "seat",
SECTION = "section"
}
/**
* @hidden
*/
declare enum RendererSelectMode {
REPLACE = "replace",
ADD = "add",
SUBTRACT = "subtract"
}
/**
* Source events
*/
/**
* @hidden
*/
declare enum SrcEventType {
DRAG_START = "srcDragStart",
DRAG_MOVE = "srcDragMove",
DRAG_END = "srcDragEnd",
CLICK = "srcClick",
MOUSE_MOVE = "srcMouseMove"
}
/**
* @hidden
*/
type SrcEvent = IDragStartSrcEvent | IDragMoveSrcEvent | IDragEndSrcEvent | IClickSrcEvent | IMouseMoveSrcEvent;
/**
* @hidden
*/
interface IDragSrcEvent<T> {
type: T;
origin: {
x: number;
y: number;
};
delta: {
x: number;
y: number;
};
shiftKey?: boolean;
altKey?: boolean;
}
/**
* @hidden
*/
interface IDragStartSrcEvent extends IDragSrcEvent<SrcEventType.DRAG_START> {
}
/**
* @hidden
*/
interface IDragMoveSrcEvent extends IDragSrcEvent<SrcEventType.DRAG_MOVE> {
}
/**
* @hidden
*/
interface IDragEndSrcEvent extends IDragSrcEvent<SrcEventType.DRAG_END> {
}
/**
* @hidden
*/
interface IClickSrcEvent {
type: SrcEventType.CLICK;
target: HTMLElement;
point: {
x: number;
y: number;
};
section?: ISection;
seat?: ISeat;
shiftKey?: boolean;
altKey?: boolean;
}
/**
* @hidden
*/
interface IMouseMoveSrcEvent {
type: SrcEventType.MOUSE_MOVE;
target: HTMLElement;
section?: ISection;
seat?: ISeat;
}
/**
* Output events
*/
/**
* @hidden
*/
declare enum DestEventType {
PAN = "destPan",
RECT_SELECT = "destRectSelect",
DESELECT = "destDeselect",
PAN_ZOOM = "destPanZoom",
SEAT_SELECT = "destSeatSelect",
SEAT_CART_SWITCH = "destSeatCartSwitch",
SECTION_CLICK = "destSectionClick",
SEAT_MOUSE_ENTER = "destSeatMouseEnter",
SECTION_MOUSE_ENTER = "destSectionMouseEnter",
SEAT_MOUSE_LEAVE = "destSeatMouseLeave",
SECTION_MOUSE_LEAVE = "destSectionMouseLeave"
}
/**
* @hidden
*/
type DestEvent = IPanDestEvent | IRectSelectDestEvent | IPanZoomDestEvent | IDeselectDestEvent | ISeatSelectDestEvent | ISeatCartSwitchDestEvent | ISectionClickDestEvent | ISeatMouseEnterDestEvent | ISectionMouseEnterDestEvent | ISeatMouseLeaveDestEvent | ISectionMouseLeaveDestEvent;
/**
* @hidden
*/
interface IPanDestEvent {
type: DestEventType.PAN;
isStart?: boolean;
isFinish?: boolean;
delta: {
x: number;
y: number;
};
}
/**
* @hidden
*/
interface IRectSelectDestEvent {
type: DestEventType.RECT_SELECT;
selectMode: RendererSelectMode;
isStart?: boolean;
isFinish?: boolean;
isRowsMode?: boolean;
rect: {
x: number;
y: number;
width: number;
height: number;
};
}
/**
* @hidden
*/
interface IPanZoomDestEvent {
type: DestEventType.PAN_ZOOM;
scale: number;
origin?: {
x: number;
y: number;
};
}
/**
* @hidden
*/
interface ISeatMouseEnterDestEvent {
type: DestEventType.SEAT_MOUSE_ENTER;
isRowsMode?: boolean;
seat: ISeat;
}
/**
* @hidden
*/
interface ISectionMouseEnterDestEvent {
type: DestEventType.SECTION_MOUSE_ENTER;
section: ISection;
}
/**
* @hidden
*/
interface ISeatMouseLeaveDestEvent {
type: DestEventType.SEAT_MOUSE_LEAVE;
}
/**
* @hidden
*/
interface ISectionMouseLeaveDestEvent {
type: DestEventType.SECTION_MOUSE_LEAVE;
}
/**
* @hidden
*/
interface IDeselectDestEvent {
type: DestEventType.DESELECT;
}
/**
* @hidden
*/
interface ISeatSelectDestEvent {
type: DestEventType.SEAT_SELECT;
selectMode: RendererSelectMode;
point: {
x: number;
y: number;
};
seat: ISeat;
isRowsMode?: boolean;
}
/**
* @hidden
*/
interface ISeatCartSwitchDestEvent {
type: DestEventType.SEAT_CART_SWITCH;
point: {
x: number;
y: number;
};
seat: ISeat;
}
/**
* @hidden
*/
interface ISectionClickDestEvent {
type: DestEventType.SECTION_CLICK;
point: {
x: number;
y: number;
};
section: ISection;
}
/**
* @hidden
*/
interface IGaInfo {
id: number;
name: string;
transform: TransformArray;
isTable?: boolean;
}
/**
* @hidden
*/
declare class Context {
private redrawHandler;
element: HTMLElement;
settings: IRendererSettings;
seatImages: {
[id: string]: HTMLImageElement;
};
cart: ICart;
gaCategories: {
[id: number]: number;
};
categoriesColor: {
[id: number]: string | undefined;
};
scale: number;
translate: IPoint;
isEagleView: boolean;
visibility: IVisibilityStatuses;
private _seats;
seatsIndex: KDBush;
seatsById: ById<ISeat>;
seatsByRowId: {
[rowId: number]: ISeat[];
};
rowsById: ById<IRowDTO>;
sectionsById: ById<ISector>;
pricesById: ById<IColoredPrice>;
seatsKeysMissedOnPriceSet: string[];
seatsIdsMissedOnPriceSet: number[];
/**
* @hidden
*/
private _pricesDTO;
private _selectedSeatIds;
private _selectedGaId?;
underlay: {
svgString?: Nullable<string>;
viewBox: {
x: number;
y: number;
width: number;
height: number;
};
svgUrl?: string;
outlineSvg?: Nullable<string>;
pngBackground?: IPngBackgroundDTO;
};
hoveredSeat?: ISeat;
hoveredRow?: IRowDTO;
gaInfo: IGaInfo[];
constructor(element: HTMLElement, settings: IRendererSettings, redrawHandler: () => void);
set selectedSeatIds(value: number[]);
get selectedSeatIds(): number[];
set selectedGaId(value: number | undefined);
get selectedGaId(): number | undefined;
destroy(): void;
/**
* @hidden
*/
setPricesDTO(value: IPriceListDTO): void;
/**
* @hidden
*/
getPricesDTO(): IPriceListDTO;
setHovered(seat: ISeat | undefined, isRowsMode?: boolean): void;
private createSeatImages;
initCart(cart: ICart): void;
get seats(): ISeat[];
set seats(value: ISeat[]);
getPositionByOffset: (offset: IPoint) => IPoint;
getOffsetByPosition: (position: IPoint) => IPoint;
addGaToCart(ga: ICartGa): void;
removeGaFromCart(removedGa: IRemovedCartGa): void;
addSeatsToCart(seats: ICartSeat[]): void;
rectSelectSeats(rect: {
x: number;
y: number;
width: number;
height: number;
}, mode: RendererSelectMode): void;
selectSeats(seats: number[], mode: RendererSelectMode): void;
rectSelectRows(rect: {
x: number;
y: number;
width: number;
height: number;
}, mode: RendererSelectMode): void;
repairSeat: (s: ICartSeat) => ICartSeat | undefined;
afterCartUpdate: () => void;
repairGa: (ga: ICartGa) => ICartGa | undefined;
findSeatByKey(key: string): ISeat | undefined;
getCart(): ICart;
isSeatInCart(seatId: number): boolean;
isSectionSelected(sectorId: number): boolean;
addSeatToCart(seatId: number): void;
removeSeatFromCart(seatId: number): void;
getCartSeats(): ISeat[];
getSeatSelection(): ISeat[];
setSectionSelection(sections?: number[] | string[]): (number | undefined)[] | null;
getSvgSectionBySelection(): ISectorDTO[];
getGaSectors(): ISector[];
seatToCartSeat: (seat: ISeat, origCartSeat?: ICartSeat) => ICartSeat;
seatToExtendedSeat: (seat: ISeat) => IExtendedSeat;
calculateAbsolutePoint(point: IPoint): IPoint;
getSeatByOffset: (offset: IPoint) => ISeat | undefined;
}
type Nullable<T> = T | null | undefined;
type DeepPartial<T> = T extends object ? {
[P in keyof T]?: DeepPartial<T[P]>;
} : T;
/**
* Type for mapping objects by their ID.
*/
type ById<T> = {
[id: number]: T;
};
type ColorById<T> = {
[id: number | string]: T;
};
/**
* Type representing a price identifier, which can be either a number or a string.
* Used to uniquely identify price points in the system.
*/
type IPriceId = number | string;
/**
* Type representing a transformation matrix as a 6-element array.
*/
type TransformArray = [number, number, number, number, number, number];
/**
* Interface representing a seat in the venue with extended properties.
* Contains all the base seat properties plus additional properties for rendering and interaction.
*/
interface ISeat extends IBaseSeat {
/**
* The price ID associated with this seat.
*/
priceId?: IPriceId;
/**
* Whether the seat is locked and cannot be selected.
*/
locked?: boolean;
/**
* Whether the seat is filtered out by current filter criteria.
*/
filtered?: boolean;
/**
* Special state information for the seat.
*/
special?: ISpecialState;
/**
* The state of the seat.
*/
state?: SeatInteractionState;
}
/**
* Interface representing a sector in the venue with extended properties.
* Contains all the base sector properties plus additional properties for rendering and interaction.
*/
interface ISector extends IBaseSector {
/**
* The price ID associated with this sector.
*/
priceId?: IPriceId;
/**
* Special state information for the sector.
*/
special?: ISpecialState;
}
/**
* Interface representing a section in the venue.
* A section is a logical grouping of seats or a general admission area.
*/
interface ISection {
/**
* The unique ID of the section.
*/
id?: number;
/**
* The name of the section.
*/
name: string;
/**
* Whether this is a general admission section.
*/
ga: boolean;
/**
* The rectangular bounds of the section.
*/
rect: ISectionRect;
/**
* The price for the section.
*/
price?: number;
/**
* Special state information for the section.
*/
special?: ISpecialState;
/**
* The type of the section.
*/
type?: string | null;
}
/**
* Interface representing a section with additional coordinate information.
* Extends ISection with absolute x and y coordinates.
*/
interface ISectionWithCoords {
/**
* The X coordinate of the section.
*/
x: number;
/**
* The Y coordinate of the section.
*/
y: number;
/**
* The unique ID of the section.
*/
id?: number | undefined;
/**
* The name of the section.
*/
name: string;
/**
* Whether this is a general admission section.
*/
ga: boolean;
/**
* The rectangular bounds of the section.
*/
rect: ISectionRect;
/**
* The price for the section.
*/
price?: number | undefined;
/**
* Special state information for the section.
*/
special?: ISpecialState | undefined;
/**
* The type of the section.
*/
type?: string | undefined | null;
}
/**
* Interface representing the rectangular bounds of a section.
*/
interface ISectionRect {
/**
* The left coordinate of the rectangle.
*/
left: number;
/**
* The top coordinate of the rectangle.
*/
top: number;
/**
* The width of the rectangle.
*/
width: number;
/**
* The height of the rectangle.
*/
height: number;
}
/**
* Interface representing a seat in the shopping cart.
*/
interface ICartSeat {
/**
* The unique identifier of the seat.
*/
id?: number;
/**
* The unique key for the seat, typically combining section, row, and seat information.
*/
key: string;
/**
* The price of the seat.
*/
price?: number;
/**
* Special state information for the seat.
*/
special?: ISpecialState;
}
/**
* Extended interface for a seat with additional coordinate and descriptive information.
* Extends ICartSeat with position and section details.
*/
interface IExtendedSeat extends ICartSeat {
/**
* The X coordinate of the seat.
*/
x: number;
/**
* The Y coordinate of the seat.
*/
y: number;
/**
* The absolute X coordinate of the seat.
*/
ax: number;
/**
* The absolute Y coordinate of the seat.
*/
ay: number;
/**
* The ID of the section containing this seat.
*/
sectionId: number;
/**
* The ID of the sector containing this seat.
*/
sectorId: number;
/**
* The name or number of the seat.
*/
seatName: string;
/**
* The row number of the seat.
*/
rowNumber: number;
/**
* The name of the section containing this seat.
*/
sectionName: string;
/**
* Whether the seat is accessible for people with disabilities.
*/
isAccessible?: boolean;
}
/**
* Interface representing a general admission (GA) item in the shopping cart.
*/
interface ICartGa {
/**
* The ID of the sector for this GA item.
*/
sectorId?: number;
/**
* The unique key for the GA item.
*/
key: string;
/**
* The number of GA tickets in this item.
*/
count: number;
/**
* The price per GA ticket.
*/
price?: number;
}
/**
* Interface representing a removed general admission (GA) item from the cart.
*/
interface IRemovedCartGa {
/**
* The ID of the sector for the removed GA item.
*/
sectorId: number;
/**
* The price of the removed GA item.
*/
price?: number;
}
/**
* Interface representing the shopping cart containing selected seats and GA items.
*/
interface ICart {
/**
* Array of selected seats in the cart.
*/
seats: ICartSeat[];
/**
* Array of general admission items in the cart.
*/
ga: ICartGa[];
}
/**
* Type definition for a function that filters seats based on custom criteria.
* @param seat - The seat to evaluate against the filter criteria
* @returns A boolean indicating whether the seat passes the filter (true) or not (false)
*/
type SeatFilter = (seat: ISeat) => boolean;
/**
* Type definition for a seat price scheme, which associates a price with a specific seat.
*/
type ISeatPriceScheme = {
/**
* Optional unique identifier for the price scheme.
*/
id?: number;
/**
* The unique key of the seat this price applies to.
*/
seatKey: string;
/**
* The price value for the seat.
*/
price: number;
/**
* The price ID reference for the seat.
*/
priceId: IPriceId;
};
interface IZoomSettings {
presets: number[];
maxZoomToFitScale: number;
minPinchZoom: number;
maxPinchZoom: number;
}
interface IRange {
from?: number;
to?: number;
}
interface IVisibleSetting {
visible?: IRange;
selectable?: IRange;
}
interface IVisibilitySettings {
seats?: IVisibleSetting;
outlines?: IVisibleSetting;
}
/**
* Configuration settings for the renderer.
* Defines various options that control the behavior and appearance of the renderer.
*/
interface IRendererSettings {
/**
* Debug mode for the renderer.
* @hidden
*/
debug?: boolean;
/**
* Environment setting that determines which API endpoint to use.
* Can be 'local', 'stage', or 'production' (default).
*/
env?: string;
/**
* External price information for seats.
*/
seatsPrices?: ISeatPriceScheme[];
/**
* Theme settings for the renderer.
*/
theme?: IRendererTheme;
/**
* Delay in milliseconds for debounced events.
*/
debounceDelay?: number;
/**
* Number of seats to select as a group.
*/
groupSize?: number;
/**
* Fixed height for the renderer in pixels.
*/
height?: number;
/**
* Initial padding around the venue when first loaded.
*/
initialPadding?: number;
/**
* Padding around the venue during normal operation.
*/
padding?: number;
/**
* Minimum zoom level required to enable seat selection.
*
* @deprecated
* Use visibilitySettings instead
*/
seatSelectionMinZoom?: number;
/**
* Maximum number of seats that can be selected.
*/
selectionLimit?: number;
/**
* Duration of transform animations in milliseconds.
*/
transformAnimationDuration?: number;
/**
* Duration of zoom animations in milliseconds.
*/
zoomAnimationDuration?: number;
/**
* Delay time for loading the next background in milliseconds.
*/
backgroundLoadStepTime?: number;
/**
* If true, disables zoom when clicking on empty space.
*/
disableZoomToEmptySpace?: boolean;
/**
* If true, disables cart changed when clicking on sections.
*/
disableCartInteractions?: boolean;
/**
*
*/
disableOutlinesInHelicopterView?: boolean;
/**
* If true, hides all seats from view.
*/
hideSeats?: boolean;
/**
* If true, shows the outline layer during animations.
*/
showOutlineLayerOnAnimation?: boolean;
/**
* If true, shows row labels.
*/
showRows?: boolean;
/**
* If true, shows outlines for unavailable seats.
*/
showUnavailableOutlines?: boolean;
/**
* If true, uses WebGL for rendering instead of Canvas.
*/
switchToWebGL?: boolean;
/**
* Option to configure zoom settings
*/
zoomSettings?: IZoomSettings;
/**
* Option to configure visibility settings
*/
visibilitySettings?: IVisibilitySettings;
/**
* Rises when the mouse pointer moves above a seat.
*
* @remarks
*
* Seat is passed as a param to the handler (see IExtendedSeat).
*/
onSeatMouseEnter?: (seat: IExtendedSeat) => void;
/**
* Same as `onSeatMouseEnter` but with debounce.
*
* @remarks
*
* Seat is passed as a param to the handler (see IExtendedSeat).
*/
onSeatDebouncedEnter?: (seat: IExtendedSeat) => void;
/**
* Fires when the mouse pointer leaves a seat.
*/
onSeatMouseLeave?: () => void;
/**
* Fires when the user marks a seat as selected.
*
* @remarks
*
* Seat is passed as a param to the handler (see IExtendedSeat).
*
* To cancel seat selection you can return `false` or Promise resolving to `false`.
*/
onSeatSelect?: (seat: IExtendedSeat) => void | boolean | Promise<void | boolean>;
/**
* Fires when the user deselects a seat.
*
* @remarks
*
* Seat is passed as a param to the handler (see IExtendedSeat).
*
* To cancel seat deselection you can return `false` or Promise resolving to `false`.
*/
onSeatDeselect?: (seat: IExtendedSeat) => void | boolean | Promise<void | boolean>;
/**
* Fires when the user marks a seat or seats as selected.
*
* @remarks
*
* Seats are passed as a param to the handler (see ISeat).
*
*/
onSeatsSelect?: (seats: ISeat[]) => void;
/**
* Fires when the user deselects a seat or seats.
*
* @remarks
*
* Seats are passed as a param to the handler (see ISeat).
*
*/
onSeatsDeselect?: (seats: ISeat[]) => void;
/**
* Fires when the cart was modified.
*
* @remarks
*
* Cart state is passed as a param to the handler (see ICart).
*/
onCartChange?: (cart: ICart, prevCart?: ICart) => void;
/**
* Fires when the mouse pointer moves above a section.
*
* @remarks
*
* Section is passed as a param to the handler (see ISection).
*/
onSectorMouseEnter?: (section: ISection) => void;
/**
* Fires when the mouse pointer leaves a section.
*/
onSectorMouseLeave?: () => void;
/**
* Fires when the user clicks on a section.
*
* @deprecated
* Use onSectionClick instead
*/
onSectorClick?: (section: ISection) => void;
/**
* Fires when the user clicks on a section.
*
* @remarks
*
* Section is passed as a param to the handler (see ISection).
*/
onSectionClick?: (section: ISection) => void;
/**
* Fires before the zoom animation started.
*/
onZoomStart?: (newZoom: number, oldZoom: number) => void;
/**
* Fires after the zoom animation ended.
*/
onZoomEnd?: (newZoom: number, oldZoom?: number) => void;
/**
* Fires when component full redrawing starts.
*/
onRedrawStart?: () => void;
/**
* Fires when component full redrawing ends.
*/
onRedrawEnd?: () => void;
/**
* Fires when schema data has been successfully loaded and processed.
*
* @remarks
*
* This event is triggered after the schema data is fully loaded and all internal
* processing is complete. It can be used to perform actions that depend on the
* schema being fully initialized.
*/
onSchemaDataLoaded?: () => void;
/**
* Fires while panning.
*/
onPan?: (delta: IPoint, isFinish?: boolean) => void;
/**
* Fires after seat selection was updated.
*/
onSeatSelectionChange?: () => void;
/**
* Fires after seats selection was updated.
*/
onSeatsSelectionChange?: (seats: ISeat[]) => void;
/**
* You can control seats' styling by returning custom style for each seat
*/
onBeforeSeatDraw?: (event: IBeforeSeatDrawEvent) => ISeatStyle;
lockedSeatsFilter?: (seat: ISeat) => boolean;
}
/**
* Represents the possible interaction states of a seat.
* Used to determine how a seat should be rendered based on user interaction.
*/
type SeatInteractionState = 'default' | 'hovered' | 'selected' | 'unavailable' | 'loading' | 'error';
/**
* Interface for the event data passed to the onBeforeSeatDraw callback.
* Contains information about the seat being drawn and its current state.
*/
interface IBeforeSeatDrawEvent {
/**
* The seat being drawn.
*/
seat: ISeat;
/**
* The current interaction state of the seat.
*/
state: SeatInteractionState;
/**
* The default style that will be applied to the seat.
*/
style: ISeatStyle;
/**
* The rendering context.
*/
context: Context;
}
interface IRendererSeatStyleSettings {
default?: ISeatStyle;
unavailable?: ISeatStyle;
filtered?: ISeatStyle;
hovered?: ISeatStyle;
selected?: ISeatStyle;
loading?: ISeatStyle;
error?: ISeatStyle;
}
interface IBasicSeatStyle {
size: number;
color: string;
seatName?: {
font: string;
color: string;
};
stroke?: {
width: number;
color: string;
align: 'center' | 'inside' | 'outside';
};
imageId?: string;
shadow?: {
blur: number;
color: string;
x?: number;
y?: number;
};
}
interface ISeatStyle extends IBasicSeatStyle {
accessible?: IBasicSeatStyle;
}
interface IRendererSvgSectionStylesSetting {
default?: Pick<ISvgSectionStyle, 'sectionName' | 'stroke' | 'cursor'>;
unavailable?: ISvgSectionStyle;
filtered?: ISvgSectionStyle;
hovered?: ISvgSectionStyle;
selected?: ISvgSectionStyle;
}
interface ISvgSectionStyle {
sectionName?: {
color?: string;
};
bgColor?: string;
stroke?: {
color?: string;
opacity?: number;
width?: string;
};
cursor?: string;
}
interface IRendererTheme {
gridStep?: number;
bgColor?: string;
priceColors?: string[][];
colorCategories?: string[];
images?: {
[id: string]: string;
};
seatStyles?: IRendererSeatStyleSettings;
svgSectionStyles?: IRendererSvgSectionStylesSetting;
}
/**
* @hidden
*/
interface IOutlineRect {
sectionId: number;
x: number;
y: number;
width: number;
height: number;
transform?: string;
}
/**
* @hidden
*/
declare class OutlineLayer {
svgElement: SVGSVGElement;
private outlineShapes;
private outlineRect;
private context;
private originalSvg;
private backgroundSVG;
private hasBackgroundOutline;
private underlayBindedPathAttr;
private calculatedOutlineRects;
constructor(context: Context);
destroy(): void;
setSectionSelection(id: number | undefined): void;
highlightGa(id: number | undefined): void;
clearSectionHighlight(): void;
highlightSection(id: number | undefined): void;
clearSectionFocus(): void;
focusSection(id: number | undefined): void;
private removeClassNameAll;
private addClassName;
getSectionRect(id: Nullable<number>): Nullable<DOMRect>;
getSectionElement(id: number | undefined): Nullable<Element>;
get width(): number;
get height(): number;
updateSize(): void;
checkBackgroundOutlines(): boolean | undefined;
initializeBackgroundOutline(): void;
/**
*
* refactoring plan:
* * decompose this method into smaller ones
* - prepare SVG background outlines
* - GA outlines
* - sections outlines
* - prepare shapes outlines
* - GA only
* - prepare auto-generated outlines
* - Reserved seats
* - Tables
* - append outlines to the main svg element
*/
setBackgroundAsOutline(): void;
private extractSVGBackgroundOutlines;
cleanSvgInlineStyles(stylesToRemove?: string[]): void;
updateOutlines(): void;
private appendAutoAndGaOutlines;
private createOrGetOutlineShapes;
private appendAutoOutlines;
private appendGAOutlines;
private getOutlineRects;
createOutlineRect(section: ISector): SVGRectElement;
calcOutlineRect(section: ISector): IOutlineRect;
handleChangeEagleView(isEagleView?: boolean): void;
createGaInfo: (gaGroups: SVGGElement[]) => IGaInfo[];
disableSvgSectionById: (id: number) => void;
enableSvgSectionById: (id: number) => void;
filterSvgSectionById: (id: number) => void;
removeFilterSvgSectionById: (id: number) => void;
update(): void;
updateAnimationStep(scale: number, translate: IPoint): void;
hide(): void;
show(): void;
private getContextSvg;
}
/**
* Interface for the base Renderer functionality.
* Defines the core methods and properties that all renderer implementations must provide.
*/
interface IRenderer {
/**
* Initializes the cart with the provided cart data.
*
* @param cart - The cart data to initialize
*/
initCart: (cart: ICart) => void;
/**
* Gets the current cart state.
*
* @returns The current cart
*/
getCart: () => ICart;
/**
* Clears all items from the cart.
*/
clearCart: () => void;
/**
* Adds a general admission ticket to the cart.
*
* @param ga - The general admission ticket to add
*/
addGaToCart: (ga: ICartGa) => void;
/**
* Removes a general admission ticket from the cart.
*
* @param removedGa - Information about the GA ticket to remove
*/
removeGaFromCart: (removedGa: IRemovedCartGa) => void;
/**
* Adds seats to the cart.
*
* @param seats - The seats to add to the cart
*/
addSeatsToCart: (seats: ICartSeat[]) => void;
/**
* Removes seats from the cart by their IDs.
*
* @param seatIds - The IDs of the seats to remove
*/
removeSeatsFromCartByIds: (seatIds: number[]) => void;
/**
* Disables seats by their IDs, making them unavailable for selection.
*
* @param seatIds - The IDs of the seats to disable
*/
disableSeatsByIds: (seatIds: number[]) => void;
/**
* Disables seats by their keys, making them unavailable for selection.
*
* @param keys - The keys of the seats to disable
*/
disableSeatsByKeys: (keys: string[]) => void;
/**
* Updates the lock status of seats based on the provided filter.
*
* @param filter - The filter function to determine which seats to lock
*/
updateSeatLocks: (filter: SeatFilter) => void;
/**
* Converts seat keys to seat IDs.
*
* @param keys - The seat keys to convert
* @returns The corresponding seat IDs
*/
seatKeysToIds: (keys: string[]) => number[];
/**
* Sets the group size for group selection.
*
* @param groupSize - The size of the group
*/
setGroupSize: (groupSize: number) => void;
/**
* Gets the IDs of all marked seats.
*
* @returns The IDs of marked seats
*/
getMarkedSeatsIds: () => number[];
/**
* Gets all available prices.
*
* @returns The available prices with color information
*/
getPrices: () => IColoredPrice[];
/**
* Gets all seats in the venue.
*
* @returns All seats in the venue
*/
getSeats: () => ISeatDTO[];
/**
* Gets the current zoom level.
*
* @returns The current zoom level
*/
getZoom: () => number;
/**
* Gets the maximum allowed zoom level.
*
* @returns The maximum zoom level
*/
getMaxZoom: () => number;
/**
* Gets the minimum allowed zoom level.
*
* @returns The minimum zoom level
*/
getMinZoom: () => number;
/**
* Increases the zoom level by one step.
*/
zoomIn: () => void;
/**
* Decreases the zoom level by one step.
*/
zoomOut: () => void;
/**
* Adjusts the zoom level to fit the entire venue in the viewport.
*/
zoomToFit: () => void;
/**
* Sets external price information for seats.
*
* @param seatsPrices - Optional external price information for seats
*/
setExternalPrices: (seatsPrices?: ISeatPriceScheme[]) => void;
/**
* Destroys the renderer instance, cleaning up all resources.
*/
destroy: () => void;
/**
* Disables SVG sections by their IDs.
*
* @param sectionIds - The IDs of the sections to disable
* @param options - Optional configuration
* @param options.resetAll - Whether to reset all sections before disabling
*/
disableSvgSectionsByIds: (sectionIds: number[], options?: {
resetAll?: boolean;
}) => void;
/**
* Enables SVG sections by their IDs.
*
* @param sectionIds - The IDs of the sections to enable
*/
enableSvgSectionsByIds: (sectionIds: number[]) => void;
/**
* Disables SVG sections by their names.
*
* @param sectionNames - The names of the sections to disable
* @param options - Optional configuration
* @param options.resetAll - Whether to reset all sections before disabling
*/
disableSvgSectionsByNames: (sectionNames: string[], options?: {
resetAll?: boolean;
}) => void;
/**
* Enables SVG sections by their names.
*
* @param sectionNames - The names of the sections to enable
*/
enableSvgSectionsByNames: (sectionNames: string[]) => void;
/**
* Gets SVG sections by the current selection.
*
* @returns The selected SVG sections
*/
getSvgSectionBySelection: () => ISectorDTO[];
}
/**
* @hidden
*/
interface IRendererAnimation {
startTime?: number;
duration: number;
fromScale: number;
toScale: number;
fromTranslate?: IPoint;
translate?: IPoint;
toTranslate: IPoint;
relativeTranslate?: IPoint;
frame: number;
inProgress: boolean;
}
/**
* Base Renderer class that implements the IRenderer interface.
* Provides core functionality for rendering and interacting with a venue map.
*/
declare class Renderer implements IRenderer {
private hammer;
private visibilityManager;
private height;
private width;
private padding;
protected readonly context: Context;
private stageLayer;
private selectionLayer;
protected outlineLayer: OutlineLayer;
private service;
private zoomToFitScale;
private isTouchMode;
private pinchStartPoint?;
private animation?;
private resizeTimer;
protected isRunning: boolean;
private disableZoomToEmptySpace;
private switchToWebGL;
private originalSectionPrices;
/**
* Creates a new instance of the Renderer.
*
* @param element - The DOM element where the renderer will be mounted
* @param machine - The state machine that controls the renderer behavior
* @param settings - Configuration settings for the renderer
*/
constructor(element: HTMLElement, machine: RendererMachine, settings: IRendererSettings);
/**
* Destroys the renderer instance, cleaning up all resources.
* This includes removing event listeners, canceling animations, and destroying canvas layers.
*/
destroy(): void;
/**
* Gets the width of the renderer.
*
* @returns The width in pixels
*/
getWidth(): number;
/**
* Gets the height of the renderer.
*
* @returns The height in pixels
*/
getHeight(): number;
/**
* Sets the interaction mode for the renderer.
*
* @param mode - The mode to set
* @returns Whether the mode was set successfully
*/
setMode(mode: string): boolean;
getMode(): string | undefined;
setHeight(height: number): void;
setGroupSize(groupSize: number): void;
getSeatIds(seats: ISeat[] | number[] | string[]): number[];
getMarkedSeatsIds(): number[];
setSeatsCategory(seats: ISeat[] | number[] | string[], category: number, color?: string): void;
setGaCategory(sectionId: number, category: number | undefined): void;
resetCategories(): void;
/**
* Returns category's color
*
* @param category Category number
*/
getCategoryColor(category: number): string | undefined;
private createHammer;
private changeMachineContext;
private createMachineService;
private handleTouchStart;
private setContextScale;
private handleDebouncedSeatChange;
/**
* Retrieves the available prices.
*
* @example
*
* Example of return value:
*
* ```js
* [
* { id: 63, name: '100', color: '#9C27B0' },
* { id: 64, name: '200', color: '#2196F3' }
* ];
* ```
*
* @returns Array of available prices
*/
getPrices(): IColoredPrice[];
/**
* Initializes the internal cart state.
*
* @remarks
*
* In a case of page reload you should initialize
* the saved state with this method.
*
* Cart initialization is available right after
* component initialization.
*
* Sales page must save the cart state in the given format
* to support the page reload feature.
*
* @example
*
* ```js
* var cart = {
* seats: [
* {
* id: 1389563,
* key: 'Section 1;;5;;14',
* price: 100
* },
* { key: 'Table 3;;1;;1', price: 500 },
* { key: 'Section 2;;5;;1', price: 200 }
* ],
* ga: [
* {
* id: 100500,
* key: 'Table 2',
* price: 200,
* count: 1
* },
* { key: 'Section 5', price: 100, count: 2 }
* ]
* };
*
* renderer.initCart(cart);
* ```
*
* @param cart Cart state
*/
initCart(cart: ICart): void;
/**
* Clears the internal cart state.
*/
clearCart(): void;
/**
* Retrieves the internal cart state.
*
* @remarks
*
* Seatmap.pro doesn't support any session mechanisms.
* Cart is always should be stored on the ticketing system side.
* For the state management reasons, the Renderer has internal
* selected seat representation.
*
* @example
*
* Example of cart object:
*
* ```js
* var cart = {
* seats: [
* { id: 1389563, key: 'Section 1;;5;;14', price: 100 },
* { key: 'Table 3;;1;;1', price: 500 },
* { key: 'Section 2;;5;;1', price: 200 }
* ],
* ga: [
* {
* id: 100500,
* key: 'Table 2',
* price: 200,
* count: 1
* },
* { key: 'Section 5', price: 100, count: 2 }
* ]
* };
* ```
*
* @returns Returns selected seats and GA ticket count
*/
getCart(): ICart;
private emitSrcEvent;
private addHandlers;
protected setSchemaData(schema: ISchemaDTO): Promise<void>;
/**
* Sets external prices to seats
*
* * @remarks
*
* In case you need to use prices from external resources
* you should execute this method.
* External prices can be passed as an argument or as
* a `seatsPrices` property within the settings.
*/
setExternalPrices(seatsPrices?: ISeatPriceScheme[]): void;
protected setPricesData(priceList: IPriceListDTO): void;
/**
* Adds GA seats to cart programmatically.
*
* @remarks
*
* This method can be used when `onSectorClick` was fired
* and developer wants to handle custom add GA seats control.
* You can add desired quantity of GA tickets to the cart.
*
* @example
*
* ```js
* renderer.addGaToCart({
* sectorId: 100500,
* key: 'Table 2',
* price: 200,
* // quantity of GA tickets
* count: 3
* });
* ```
*
* @param ga GA cart item
*/
addGaToCart(ga: ICartGa): void;
/**
* Removes GA seats from cart programmatically.
*
* @remarks
*
* This method can be used when `onSectorClick` was fired
* and developer wants to handle custom remove GA seats control.
* You can remove GA from cart.
*
* @example
*
* ```js
* renderer.removeGaFromCart({
* sectorId: 100500,
* price: 200
* });
* ```
*
* @param removedGa removed GA cart item
*/
removeGaFromCart(removedGa: IRemovedCartGa): void;
/**
* Adds seats to cart programmatically.
*
* @remarks
*
* This method is optional.
* In a common scenario the user adds available seats
* by clicking on them.
*
* @example
*
* ```js
* renderer.addSeatsToCart([
* {
* id: 803,
* key: 'Section 3;;3;;1',
* price: 500
* }
* ]);
* ```
*
* @param seats Array of seats to add
*/
addSeatsToCart(seats: ICartSeat[]): void;
/**
* Removes seats from internal cart.
*
* @param ids Array of internal seat IDs
*/
removeSeatsFromCartByIds(ids: number[]): void;
/**
* Removes seats from internal cart.
*
* @param keys Array of composite seat keys
*/
removeSeatsFromCartByKeys(keys: string[]): void;
/**
* Marks seats as unavailable and removes them from cart.
*
* @param ids Array of internal seat IDs
* @param options Optional configuration object.
* @param options.resetAll If `true` (default), all seats not in the `ids` array will be unlocked.
* If `false`, only the seats in the `ids` array will be affected, and the
* locked state of other seats will remain unchanged.
*/
disableSeatsByIds(ids: number[], options?: {
resetAll?: boolean;
}): void;
/**
* Marks disabled seats as available.
*
* @param ids Array of internal seat IDs
*/
enableSeatsByIds(ids: number[]): void;
/**
* Marks seats as unavailable and removes them from cart.
*
* @param keys Array of composite seat keys
*/
disableSeatsByKeys(keys: string[]): void;
/**
* Marks seats as filtered.
*
* @param ids Array of internal seat IDs
*/
filterSeatsByIds(ids: number[]): void;
/**
* Marks disabled seats as available.
*
* @param ids Array of internal seat IDs
*/
removeFilter(ids?: number[]): void;
/**
* Marks seats as filtered.
*
* @param keys Array of composite seat keys
*/
filterSeatsByKeys(keys: string[]): void;
/**
* Convert array of seat keys to array of seat ids
*
* @param keys Array of composite seat keys
*/
seatKeysToIds(keys: string[]): number[];
/**
* Updates seat lock states.
*
* @example
*
* For example, you can create handler to prevent selection of seats
* with different special state:
*
* ```js
* const handleCartChange = (cart, prevCart) => {
* if (!cart.seats.length) {
* // Unlock all the seats if the cart is empty
* renderer.updateSeatLocks(s => false);
* } else if (!prevCart || !prevCart.seats.length) {
* // Lock seats with different special state
* const seat = cart.seats[0];
* renderer.updateSeatLocks(
* s => (s.special && s.special.s1) !== (seat.special && seat.special.s1)
* );
* }
* };
* ```
*
* @param filter Function should return `true` for seats to lock
*/
updateSeatLocks(filter: SeatFilter): void;
/**
* Returns selected seats
*/
getSeatSelection(): IExtendedSeat[];
setSectionSelection(sections?: number[] | string[]): void;
getSvgSectionBySelection(): ISectorDTO[];
disableSvgSe