infusion-code/angular-maps

View on GitHub
src/models/canvas-overlay.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { ILatLong } from '../interfaces/ilatlong';
import { MapLabel } from './map-label';

let id: number = 0;

/**
 * Abstract base implementing a canvas overlay to be placed on the map.
 *
 * @export
 * @abstract
 */
export abstract class CanvasOverlay {

    ///
    /// field declarations
    ///
    protected _readyResolver: (val: boolean) => void;
    protected _canvas: HTMLCanvasElement;
    protected _zoomStart: number;
    protected _centerStart: ILatLong;
    public _canvasReady: Promise<boolean> = new Promise<boolean>((resolve, reject) => { this._readyResolver = resolve; });

    /**
     * Returns a promise that gets resolved when the canvas overlay is ready for interaction.
     */
    public get CanvasReady(): Promise<boolean> { return this._canvasReady; }

    /**
    * A callback function that is triggered when the canvas is ready to be rendered for the current map view.
    */
    private _drawCallback: (canvas: HTMLCanvasElement) => void;


    /**
     * Creates a new instance of the CanvasOverlay class.
     */
    constructor(drawCallback: (canvas: HTMLCanvasElement) => void) {
        this._drawCallback = drawCallback;
        id++;
    }

    ///
    /// Public methods
    ///

    /**
     * Deletes the canvas overlay.
     */
    public Delete(): void {
        this.SetMap(null);
    }

    /**
     * Obtains geo coordinates for the click location
     */
    public abstract GetCoordinatesFromClick(e: any): ILatLong;


    /**
     * Gets the map associted with the label.
     */
    public abstract GetMap(): any;

    /**
     * Returns a MapLabel instance for the current platform that can be used as a tooltip.
     * This method only generates the map label. Content and placement is the responsibility
     * of the caller.
     */
    public abstract GetToolTipOverlay(): MapLabel;

    /**
     * CanvasOverlay added to map, load canvas.
     */
    public OnAdd(): void {
        this._canvas = document.createElement('canvas');
        this._canvas.style.position = 'absolute';
        this._canvas.style.left = '0px';
        this._canvas.style.top = '0px';
        this._canvas.id = `xMapOverlay${id}`;

        // Add the canvas to the overlay.
        this.SetCanvasElement(this._canvas);
    }

    /**
     * CanvasOverlay loaded, attach map events for updating canvas.
     * @abstract
     * @method
     * @memberof CanvasOverlay
     */
    public abstract OnLoad(): void;

    /**
     * When the CanvasLayer is removed from the map, release resources.
     * @memberof CanvasOverlay
     * @method
     */
    public OnRemove(): void {
        this.SetCanvasElement(null);
        this.RemoveEventHandlers();
        this._canvas = null;
    }

    /**
     * Redraws the canvas for the current map view.
     * @param clear - True to clear the canvas before drawing.
     * @memberof CanvasOverlay
     * @method
     */
    public Redraw(clear: boolean): void {
        if (this._canvas == null) { return; }

        // Clear canvas by updating dimensions. This also ensures canvas stays the same size as the map.
        if (clear) { this.Resize(); }

        // Call the drawing callback function if specified.
        if (this._drawCallback) {
            this._drawCallback(this._canvas);
        }
    }

    /**
     * Sets the map for the label. Settings this to null remove the label from hte map.
     *
     * @param map - A native map object for the underlying implementation. Implementing derivatives should return the
     * actual native object.
     * @memberof CanvasOverlay
     * @method
     */
    public abstract SetMap(map: any): void;

    ///
    /// Protected methods
    ///

    /**
     * Attaches the canvas to the map.
     * @memberof CanvasOverlay
     * @method
     */
    protected abstract SetCanvasElement(el: HTMLCanvasElement): void;

    /**
     * Remove the map event handlers.
     * @memberof CanvasOverlay
     * @method
     * @abstract
     * @protected
     */
    protected abstract RemoveEventHandlers(): void;

    /**
     * Updates the Canvas size based on the map size.
     * @memberof CanvasOverlay
     * @method
     * @abstract
     * @protected
     */
    protected abstract Resize(): void;

    /**
     * Updates the Canvas.
     * @memberof CanvasOverlay
     * @method
     * @protected
     */
    protected abstract UpdateCanvas(): void;

    /**
     * Simple function for updating the CSS position and dimensions of the canvas.
     * @param x The horizontal offset position of the canvas.
     * @param y The vertical offset position of the canvas.
     * @param w The width of the canvas.
     * @param h The height of the canvas.
     * @memberof CanvasOverlay
     * @method
     * @protected
     */
    protected UpdatePosition(x: number, y: number, w: number, h: number) {
        // Update CSS position.
        this._canvas.style.left = x + 'px';
        this._canvas.style.top = y + 'px';

        // Update CSS dimensions.
        this._canvas.style.width = w + 'px';
        this._canvas.style.height = h + 'px';
    }

}