leaflet.glify
Version:
web gl renderer plugin for leaflet
159 lines (141 loc) • 4.25 kB
text/typescript
import { LeafletMouseEvent, Map } from "leaflet";
import { Lines, ILinesSettings } from "./lines";
import { Points, IPointsSettings } from "./points";
import { Shapes, IShapesSettings } from "./shapes";
import { debounce } from "./utils";
import vertex from "./shader/vertex/default.glsl";
import dot from "./shader/fragment/dot.glsl";
import point from "./shader/fragment/point.glsl";
import puck from "./shader/fragment/puck.glsl";
import simpleCircle from "./shader/fragment/simple-circle.glsl";
import square from "./shader/fragment/square.glsl";
import polygon from "./shader/fragment/polygon.glsl";
const shader = {
vertex,
fragment: {
dot,
point,
puck,
simpleCircle,
square,
polygon,
},
};
export class Glify {
longitudeKey = 1;
latitudeKey = 0;
clickSetupMaps: Map[] = [];
hoverSetupMaps: Map[] = [];
shader = shader;
Points: typeof Points = Points;
Shapes: typeof Shapes = Shapes;
Lines: typeof Lines = Lines;
pointsInstances: Points[] = [];
shapesInstances: Shapes[] = [];
linesInstances: Lines[] = [];
longitudeFirst(): this {
this.longitudeKey = 0;
this.latitudeKey = 1;
return this;
}
latitudeFirst(): this {
this.latitudeKey = 0;
this.longitudeKey = 1;
return this;
}
get instances(): Array<Points | Lines | Shapes> {
return [
...this.pointsInstances,
...this.linesInstances,
...this.shapesInstances,
];
}
points(settings: Partial<IPointsSettings>): Points {
const points = new this.Points({
setupClick: this.setupClick.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: glify.latitudeKey,
longitudeKey: glify.longitudeKey,
vertexShaderSource: () => {
return this.shader.vertex;
},
fragmentShaderSource: () => {
return this.shader.fragment.point;
},
...settings,
});
this.pointsInstances.push(points);
return points;
}
lines(settings: Partial<ILinesSettings>): Lines {
const lines = new this.Lines({
setupClick: this.setupClick.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: this.latitudeKey,
longitudeKey: this.longitudeKey,
vertexShaderSource: () => {
return this.shader.vertex;
},
fragmentShaderSource: () => {
return this.shader.fragment.polygon;
},
...settings,
});
this.linesInstances.push(lines);
return lines;
}
shapes(settings: Partial<IShapesSettings>): Shapes {
const shapes = new this.Shapes({
setupClick: this.setupClick.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: this.latitudeKey,
longitudeKey: this.longitudeKey,
vertexShaderSource: () => {
return this.shader.vertex;
},
fragmentShaderSource: () => {
return this.shader.fragment.polygon;
},
...settings,
});
this.shapesInstances.push(shapes);
return shapes;
}
setupClick(map: Map): void {
if (this.clickSetupMaps.includes(map)) return;
this.clickSetupMaps.push(map);
map.on("click", (e: LeafletMouseEvent) => {
let hit;
hit = this.Points.tryClick(e, map, this.pointsInstances);
if (hit !== undefined) return hit;
hit = this.Lines.tryClick(e, map, this.linesInstances);
if (hit !== undefined) return hit;
hit = this.Shapes.tryClick(e, map, this.shapesInstances);
if (hit !== undefined) return hit;
});
}
setupHover(map: Map, hoverWait?: number, immediate?: false): void {
if (this.hoverSetupMaps.includes(map)) return;
this.hoverSetupMaps.push(map);
map.on(
"mousemove",
debounce(
(e: LeafletMouseEvent) => {
this.Points.tryHover(e, map, this.pointsInstances);
this.Lines.tryHover(e, map, this.linesInstances);
this.Shapes.tryHover(e, map, this.shapesInstances);
},
hoverWait ?? 0,
immediate
)
);
}
}
export const glify = new Glify();
export default glify;
if (typeof window !== "undefined" && window.L) {
// @ts-expect-error exporting it to window
window.L.glify = glify;
// @ts-expect-error exporting it to window
window.L.Glify = Glify;
}