You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
leaflet-components/src/elements/leaflet-polyline.ts

64 lines
2.4 KiB
TypeScript

import { Polyline, type PolylineOptions } from 'leaflet';
import { bool, num, type PropDef } from '../core/props.ts';
import { pathProps, style, type Styleable } from '../core/shared-props.ts';
import {
WithProps,
type LeafletAddEventListener,
type LeafletElementConstructor,
type LeafletRemoveEventListener,
} from '../core/with-props.ts';
import type { PathEvents } from '../core/event-types.ts';
import type { LeafletLineRemoveEvent, LeafletLineSyncEvent } from '../core/register.ts';
import { VertexTracker } from '../core/vertex-tracker.ts';
const PROPS: typeof pathProps & {
fill: PropDef<boolean, Styleable>;
smoothFactor: PropDef<number>;
noClip: PropDef<boolean>;
} = {
...pathProps,
// Unlike closed shapes, a polyline is unfilled by default.
fill: bool(false, { set: style('fill') }),
smoothFactor: num(1.0),
noClip: bool(),
};
const Base: LeafletElementConstructor<Polyline, typeof PROPS> = WithProps(PROPS);
/** `<leaflet-polyline>` — a Leaflet `Polyline`. Vertices come from `<leaflet-line>` children, not an attribute. */
export default class LeafletPolylineElement extends Base {
declare readonly leafletObject?: Polyline;
declare addEventListener: LeafletAddEventListener<PathEvents>;
declare removeEventListener: LeafletRemoveEventListener<PathEvents>;
#vertices = new VertexTracker();
createLeafletObject(options: PolylineOptions): Polyline {
return new Polyline(this.#vertices.coords(), options);
}
// Vertices come from <leaflet-line> children rather than an attribute --
// each one announces its own position via leaflet-line-sync/-remove, we
// never read a child's state directly.
connectedCallback(): void {
super.connectedCallback();
this.addEventListener('leaflet-line-sync', this.#onLineSync);
this.addEventListener('leaflet-line-remove', this.#onLineRemove);
}
disconnectedCallback(): void {
this.removeEventListener('leaflet-line-sync', this.#onLineSync);
this.removeEventListener('leaflet-line-remove', this.#onLineRemove);
super.disconnectedCallback();
}
#onLineSync = (e: LeafletLineSyncEvent) => {
this.#vertices.sync(e.detail.element, e.detail.latlng);
this.leafletObject?.setLatLngs(this.#vertices.coords());
};
#onLineRemove = (e: LeafletLineRemoveEvent) => {
this.#vertices.remove(e.detail.element);
this.leafletObject?.setLatLngs(this.#vertices.coords());
};
}