ngx-venue-map
Version:
Interactive venue seating map component for Angular applications
516 lines (508 loc) • 16 kB
TypeScript
import * as _angular_core from '@angular/core';
import { OnInit, AfterViewInit, OnDestroy, ElementRef } from '@angular/core';
import { fabric } from 'fabric';
import * as rxjs from 'rxjs';
declare enum VenueMapType {
GRADE = "grade",
GRADE_PRICE = "gradePrice"
}
interface Point {
x: number;
y: number;
}
interface Bounds {
left: number;
right: number;
top: number;
bottom: number;
zoom: number;
}
interface ClientPositionSeat {
clientX?: number;
clientY?: number;
}
interface SizeShape {
width: number;
height: number;
stroke: number;
cornerRadius: number;
padding: number;
offsetLeft: number;
offsetTop: number;
}
interface Circle extends Point {
textColor: string;
}
interface MapSetting {
width: number;
height: number;
scale?: number;
}
interface MiniMapConfiguration {
scale: number;
opacity: number;
}
interface ZoomConfiguration {
min: number;
max: number;
step: number;
showMiniMapAtLevel: number;
}
interface MapConfiguration {
path: string | string[];
width: number;
height: number;
offsetHeight: number;
fontSize: number;
bubble: SizeShape;
corner: SizeShape;
arrow: SizeShape;
circle: SizeShape;
zoom: ZoomConfiguration;
minimap: MiniMapConfiguration;
}
interface ExtendedObject extends fabric.Object {
id?: string;
subId?: string;
subType?: string;
shapeIndex?: number;
}
interface ExtendedGroup extends fabric.Group {
id?: string;
subId?: string;
subType?: string;
shapeIndex?: number;
}
interface ExtendedImage extends fabric.Image {
id?: string;
subId?: string;
shapeIndex?: number;
}
interface FabricCanvas extends fabric.Canvas {
wrapperEl: HTMLElement;
lowerCanvasEl: HTMLCanvasElement;
upperCanvasEl: HTMLCanvasElement;
}
interface GradeSetting {
angle: number;
circle: Circle;
points: Point[];
color: string;
}
interface Grade {
id: string;
name: string;
abbreviation: string;
settings: GradeSetting[];
disabled: boolean;
price: number;
}
interface VenueMapTheme {
canvasBackgroundColor: string;
gradeStrokeColor: string;
gradeTextColor: string;
priceBackgroundColor: string;
priceTextColor: string;
priceBubbleStrokeColor: string;
miniMapViewportColor: string;
availableSeatColor: string;
unavailableSeatColor: string;
selectedSeatColor: string;
selectedSeatBorderColor: string;
availableSeatBorderColor: string;
disabledSeatColor: string;
premiumSeatColor: string;
premiumSeatHoverColor: string;
goldSeatColor: string;
shadowColor: string;
darkTextColor: string;
}
declare class VenueMapCanvasService {
private readonly renderService;
private readonly miniMapService;
private readonly canvasReady$;
readonly zoomLevel: _angular_core.WritableSignal<number>;
readonly isZooming: _angular_core.WritableSignal<boolean>;
readonly canvasReady: _angular_core.WritableSignal<boolean>;
readonly disableZoomIn: _angular_core.Signal<boolean>;
readonly disableZoomOut: _angular_core.Signal<boolean>;
readonly showMiniMap: _angular_core.Signal<boolean>;
private touchState;
private touchTimeout?;
private animationFrameId;
private currentPosition;
private lastPosition;
private lastTouchEventTimestamp;
private zoomStartScale;
private lastScale;
private mapWidth;
private debouncedClickHandler;
private debounceClick?;
private workerRenderValue?;
clientPopupPosition: ClientPositionSeat;
miniMapCanvas: fabric.StaticCanvas;
viewDimensions: MapSetting;
canvas: FabricCanvas;
mapConfig: MapConfiguration;
theme: VenueMapTheme;
constructor();
/**
* Updates the zoom level signal and triggers reactive updates
*/
private updateZoomLevel;
getCanvasReadyObservable(): rxjs.Observable<boolean>;
initialize(viewDimensions: MapSetting, config: MapConfiguration, theme: VenueMapTheme): void;
setupCanvas(canvasElement: HTMLCanvasElement): void;
hiddenMap(): void;
private setupEventListeners;
private handleTouchStart;
private handleTouchMove;
private handlePinchZoom;
private handleSingleTouchMove;
private handleTouchEnd;
private resetActionEvent;
private handleMouseDown;
private handleMouseUp;
private handleMouseMove;
private handleZoom;
private handleGesture;
private handleDrag;
loadBackgroundImage(pathImg?: string | string[], callback?: () => void): void;
renderFrame(): void;
private stopRenderFrame;
showMap(): void;
initializeMiniMap(): void;
showDisplayViewportMap(): void;
zoomAnimated(point: fabric.Point, zoomLevel: number, duration?: number, callback?: () => void): void;
adjustViewToCenter(callback?: () => void, widthPercentage?: number): void;
resetZoomCanvas(): void;
handleZoomBtn(type: 'zoomIn' | 'zoomOut'): void;
zoomAndPanToObject(object: ExtendedObject, zoom?: number, callback?: () => void): void;
zoomToObjectBufferHeight(object: ExtendedObject, zoom?: number, heightPrice?: number, callback?: () => void): void;
resetHeightCanvas(): void;
setHeightCanvas(heightBuffer?: number): void;
centerPointCanvas(): fabric.Point;
removeGroupCanvas(): void;
createObjectFromPoint(point: Point): ExtendedGroup;
findObjectByGrade(id?: string, shapeIndex?: number): ExtendedGroup | undefined;
removeObjectCaching(): void;
setDebounceClickHandler(handler: (object: ExtendedGroup, touch?: MouseEvent) => void): void;
setWorkerRenderValue(handler: () => void): void;
private cancelDebounceClick;
scaleValue(value: number): number;
scalePoint(point: {
x: number;
y: number;
}): {
x: number;
y: number;
};
handleScalePoint(points: {
x: number;
y: number;
}[]): {
x: number;
y: number;
}[];
scalePointGrade(point: {
x: number;
y: number;
}, mapConfigGrade: MapConfiguration): {
x: number;
y: number;
};
calculateFramesDimensions(points?: Point[]): {
width: number;
height: number;
left: number;
top: number;
right: number;
bottom: number;
centerX: number;
centerY: number;
};
getVisibleBounds(buffer?: number): Bounds;
isInBounds(seatPoint: {
left: number;
top: number;
}, bounds: Bounds): boolean;
private getClientPosition;
private getDistance;
private removeEventListeners;
removeCanvasMap(): void;
clearMapService(): void;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<VenueMapCanvasService, never>;
static ɵprov: _angular_core.ɵɵInjectableDeclaration<VenueMapCanvasService>;
}
interface GradeSelection {
grade: Grade;
shapeIndex: number | undefined;
}
interface FocusedGradePart {
id: string;
shapeIndex: number | undefined;
}
declare class VenueMapComponent implements OnInit, AfterViewInit, OnDestroy {
grades: _angular_core.InputSignal<Grade[]>;
reloadMap: _angular_core.InputSignal<boolean>;
focusedGradePart: _angular_core.InputSignal<FocusedGradePart | undefined>;
mapConfiguration: _angular_core.InputSignal<(Partial<MapConfiguration> & Pick<MapConfiguration, "width" | "height" | "path">) | undefined>;
theme: _angular_core.InputSignal<Partial<VenueMapTheme> | undefined>;
selectGrade: _angular_core.OutputEmitterRef<GradeSelection>;
canvasRef: ElementRef<HTMLCanvasElement>;
mapContainer: ElementRef<HTMLElement>;
readonly VenueMapType: typeof VenueMapType;
private readonly gradeService;
readonly canvasService: VenueMapCanvasService;
resolvedMapConfiguration: _angular_core.Signal<MapConfiguration>;
resolvedTheme: _angular_core.Signal<VenueMapTheme>;
viewDimensions: _angular_core.Signal<{
width: number;
height: number;
scale: number;
}>;
venueMapType: _angular_core.WritableSignal<VenueMapType>;
isLoading: _angular_core.WritableSignal<boolean>;
mapWidth: _angular_core.WritableSignal<number>;
gradeSelectCanvas: _angular_core.WritableSignal<ExtendedGroup | undefined>;
gradeSelect: _angular_core.WritableSignal<Grade | undefined>;
private pendingMapWidth;
private isRendering;
private readonly debounceGradeMapShow;
private readonly debounceUpdateMapWidth;
constructor();
ngOnInit(): void;
ngOnDestroy(): void;
ngAfterViewInit(): void;
/**
* Initializes canvas event handlers and observables.
*/
private initializeCanvasHandlers;
/**
* Cleans up resources when component is destroyed.
*/
private cleanupResources;
/**
* Updates the map width and triggers re-rendering if needed.
*/
private updateMapWidth;
/**
* Starts the rendering process with the new map width.
*/
private startRenderProcess;
/**
* Processes the render queue and handles pending width changes.
*/
private processRenderQueue;
/**
* Handles changes to map settings and triggers re-initialization.
*/
private handleMapSettingsChange;
/**
* Initializes map data and view dimensions.
*/
private initializeMapData;
/**
* Sets up the canvas and loads background image.
*/
private setupCanvas;
/**
* Resets canvas state and renders all grades.
*/
private resetAndRenderGrades;
/**
* Resets the canvas state and clears selections.
*/
private resetCanvasState;
/**
* Clears the current grade selection.
*/
private clearGradeSelection;
/**
* Renders all grades on the canvas.
*/
private renderGrades;
/**
* Creates a grade group with all its components.
*/
private createGradeGroup;
/**
* Builds grade information object for grade creation.
*/
private buildGradeInfo;
/**
* Renders sticky elements for all grades based on current map type.
*/
private renderGradeSticky;
/**
* Finds a grade by its ID.
*/
private findGradeById;
/**
* Shows the center focus map with animation delay.
*/
private showCenterFocusMap;
/**
* Renders the map focus and initializes mini map.
*/
private renderMapFocus;
/**
* Handles grade click events.
*/
private onGradeClick;
/**
* Handles the selection of a grade.
*/
private handleGradeSelection;
/**
* Updates the grade display after selection.
*/
private updateGradeDisplay;
/**
* Checks if the grade is already selected.
*/
private isGradeAlreadySelected;
/**
* Selects a grade and updates the UI state.
*/
private selectGradeInternal;
/**
* Handles changes to grade map display.
*/
onChangeGradeMapShow(): void;
/**
* Handles grade selection from external components.
*/
onGradeSelected(selectedObject: ExtendedGroup): void;
/**
* Handles seat grade selection.
*/
onSelectSeatGrade(): void;
/**
* Handles changes to grade map type (grade view vs price view).
*/
onChangeGradeMapType(isPrice: boolean): void;
/**
* Cancels the debounced grade map show operation.
*/
private cancelDebounceGradeMapShow;
/**
* Triggers the debounced grade map show operation.
*/
private triggerDebounceGradeMapShow;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<VenueMapComponent, never>;
static ɵcmp: _angular_core.ɵɵComponentDeclaration<VenueMapComponent, "ngx-venue-map", never, { "grades": { "alias": "grades"; "required": false; "isSignal": true; }; "reloadMap": { "alias": "reloadMap"; "required": false; "isSignal": true; }; "focusedGradePart": { "alias": "focusedGradePart"; "required": false; "isSignal": true; }; "mapConfiguration": { "alias": "mapConfiguration"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; }, { "selectGrade": "selectGrade"; }, never, never, true, never>;
}
/**
* Service responsible for creating and managing price displays on venue maps.
* Handles the creation of sticky price elements and price-related rendering logic.
*/
declare class VenueMapPriceService {
/**
* Finds the circle element within a grade shape.
*/
private findCircleInGradeShape;
/**
* Calculates the height offset for circle elements.
*/
private calculateCircleHeight;
/**
* Finds the text bubble group within a shape.
*/
private findTextBubbleGroup;
/**
* Calculates the position for sticky price elements.
*/
private calculateStickyPosition;
/**
* Updates the content of text bubble elements.
*/
private updateTextBubbleContent;
/**
* Updates the text content within a text bubble group.
*/
private updateTextContent;
/**
* Creates a sticky price element for grade display.
*/
createStickyPrice(grade: Grade, gradeSetting: GradeSetting, mapInfo: MapConfiguration, scale: number, canvas: fabric.Canvas, theme: VenueMapTheme): ExtendedGroup;
/**
* Updates the position of sticky price elements.
*/
updateStickyPricePosition(grade: Grade, shape: ExtendedGroup, gradeShape: ExtendedGroup, subId: string, mapType: VenueMapType): void;
/**
* Renders sticky price elements with proper visibility control.
*/
renderStickyPrice(grade: Grade, shape: ExtendedGroup, isVisible: boolean, gradeShape: ExtendedGroup, subId: string, mapType: VenueMapType): void;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<VenueMapPriceService, never>;
static ɵprov: _angular_core.ɵɵInjectableDeclaration<VenueMapPriceService>;
}
/**
* Pure utility functions for venue map operations that don't require service dependencies.
* These functions are used across different services for scaling operations.
*/
/**
* Scales a single value based on the provided scale factor.
*/
declare function scaleValue(value: number, scale: number): number;
/**
* Scales a point coordinate based on the provided scale factor.
*/
declare function scalePoint(point: Point, scale: number): Point;
/**
* Scales an array of points based on the provided scale factor.
*/
declare function scalePoints(points: Point[], scale: number): Point[];
declare const DEFAULT_MAP_CONFIG: {
circle: {
width: number;
height: number;
stroke: number;
padding: number;
cornerRadius: number;
offsetLeft: number;
offsetTop: number;
};
fontSize: number;
bubble: {
width: number;
height: number;
stroke: number;
cornerRadius: number;
padding: number;
offsetLeft: number;
offsetTop: number;
};
corner: {
width: number;
height: number;
stroke: number;
cornerRadius: number;
padding: number;
offsetLeft: number;
offsetTop: number;
};
arrow: {
width: number;
height: number;
padding: number;
stroke: number;
cornerRadius: number;
offsetLeft: number;
offsetTop: number;
};
offsetHeight: number;
minimap: {
scale: number;
opacity: number;
};
zoom: {
min: number;
max: number;
step: number;
showMiniMapAtLevel: number;
};
};
declare const DEFAULT_VENUE_MAP_THEME: VenueMapTheme;
export { DEFAULT_MAP_CONFIG, DEFAULT_VENUE_MAP_THEME, VenueMapComponent, VenueMapPriceService, VenueMapType, scalePoint, scalePoints, scaleValue };
export type { Bounds, Circle, ClientPositionSeat, ExtendedGroup, ExtendedImage, ExtendedObject, FabricCanvas, Grade, GradeSetting, MapConfiguration, MapSetting, MiniMapConfiguration, Point, SizeShape, VenueMapTheme, ZoomConfiguration };