UNPKG

@seatmap.pro/renderer

Version:

Seatmap renderer library for booking and admin interfaces by Seatmap.pro

1,993 lines (1,982 loc) 64.1 kB
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