Skip to content

Commit

Permalink
feat: contextmenu handler
Browse files Browse the repository at this point in the history
  • Loading branch information
charlieforward9 committed Dec 5, 2024
1 parent 6dd3573 commit 54a19a9
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 21 deletions.
58 changes: 58 additions & 0 deletions example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ Promise.all([

console.log("clicked on Shape", feature, e);
},
contextMenu: (e, feature): void => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
L.popup()
.setLatLng(e.latlng)
.setContent(`You right clicked on ${feature.properties.NAZKR_ENG}`)
.openOn(map);

console.log("clicked on Shape", feature, e);
},
hover: (e: LeafletMouseEvent, feature) => {
console.log("hovered on Shape", feature, e);
},
Expand All @@ -45,6 +54,14 @@ Promise.all([

console.log("clicked on Line", feature, e);
},
contextMenu: (e: LeafletMouseEvent, feature) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
//set up a standalone popup (use a popup as a layer)
L.popup()
.setLatLng(e.latlng)
.setContent(`right clicked on Line ${feature.properties.name}`)
.openOn(map);
},
hover: (e: LeafletMouseEvent, feature) => {
console.log("hovered on Line", feature, e);
},
Expand Down Expand Up @@ -73,6 +90,16 @@ Promise.all([

console.log("clicked on Point", feature, e);
},
contextMenu: (e: LeafletMouseEvent, feature) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
//set up a standalone popup (use a popup as a layer)
L.popup()
.setLatLng(feature)
.setContent(
`You right clicked the point at longitude:${e.latlng.lng}, latitude:${e.latlng.lat}`
)
.openOn(map);
},
data: points,
});

Expand All @@ -99,6 +126,18 @@ Promise.all([

console.log("clicked on Point", feature, e);
},
contextMenu: (e: LeafletMouseEvent, feature) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
//set up a standalone popup (use a popup as a layer)
L.popup()
.setLatLng(feature)
.setContent(
`You right clicked the point at longitude:${e.latlng.lng}, latitude:${e.latlng.lat}`
)
.openOn(map);

console.log("clicked on Point", feature, e);
},
hover: (e: LeafletMouseEvent, feature) => {
console.log("hovered on Point", feature, e);
},
Expand Down Expand Up @@ -130,6 +169,16 @@ Promise.all([

console.log("clicked on Point", feature, e);
},
contextMenu: (e, feature) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
//set up a standalone popup (use a popup as a layer)
L.popup()
.setLatLng(feature.geometry.coordinates)
.setContent("You right clicked on:" + feature.properties.name)
.openOn(map);

console.log("clicked on Point", feature, e);
},
data: {
//geojson
type: "FeatureCollection",
Expand Down Expand Up @@ -172,6 +221,15 @@ Promise.all([

console.log("clicked on Shape", feature, e);
},
contextMenu: (e, feature) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
L.popup()
.setLatLng(e.latlng)
.setContent(`You right clicked on ${feature.properties.name}`)
.openOn(map);

console.log("clicked on Shape", feature, e);
},
hover: (e, feature) => {
console.log("hovered on Shape", feature, e);
},
Expand Down
25 changes: 19 additions & 6 deletions src/base-gl-layer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LeafletMouseEvent, Map } from "leaflet";

import { IColor } from "./color";
import { IPixel } from "./pixel"
import { IPixel } from "./pixel";
import { CanvasOverlay, ICanvasOverlayDrawEvent } from "./canvas-overlay";
import { notProperlyDefined } from "./errors";
import { MapMatrix } from "./map-matrix";
Expand Down Expand Up @@ -34,13 +34,15 @@ export interface IBaseGlLayerSettings {
[name: string]: IShaderVariable;
};
setupClick?: (map: Map) => void;
setupContextMenu?: (map: Map) => void;
setupHover?: SetupHoverCallback;
sensitivity?: number;
sensitivityHover?: number;
vertexShaderSource?: (() => string) | string;
fragmentShaderSource?: (() => string) | string;
canvas?: HTMLCanvasElement;
click?: EventCallback;
contextMenu?: EventCallback;
hover?: EventCallback;
hoverOff?: EventCallback;
color?: ColorCallback | IColor | null;
Expand All @@ -59,7 +61,7 @@ export const defaults: Partial<IBaseGlLayerSettings> = {
export type ColorCallback = (featureIndex: number, feature: any) => IColor;

export abstract class BaseGlLayer<
T extends IBaseGlLayerSettings = IBaseGlLayerSettings
T extends IBaseGlLayerSettings = IBaseGlLayerSettings,
> {
bytes = 0;
active: boolean;
Expand Down Expand Up @@ -160,10 +162,10 @@ export abstract class BaseGlLayer<
this.matrix = null;
this.vertices = null;
this.vertexLines = null;
try{
this.mapCenterPixels = this.map.project(this.map.getCenter(), 0)
} catch(err){
this.mapCenterPixels = {x:-0,y:-0}
try {
this.mapCenterPixels = this.map.project(this.map.getCenter(), 0);
} catch (err) {
this.mapCenterPixels = { x: -0, y: -0 };
}
const preserveDrawingBuffer = Boolean(settings.preserveDrawingBuffer);
const layer = (this.layer = new CanvasOverlay(
Expand Down Expand Up @@ -235,6 +237,9 @@ export abstract class BaseGlLayer<
if (settings.click && settings.setupClick) {
settings.setupClick(this.map);
}
if (settings.contextMenu && settings.setupContextMenu) {
settings.setupContextMenu(this.map);
}
if (settings.hover && settings.setupHover) {
settings.setupHover(this.map, this.hoverWait);
}
Expand Down Expand Up @@ -417,6 +422,14 @@ export abstract class BaseGlLayer<
}
}

contextMenu(e: LeafletMouseEvent, feature: any): boolean | undefined {
if (!this.settings.contextMenu) return;
const result = this.settings.contextMenu(e, feature);
if (result !== undefined) {
return result;
}
}

hover(e: LeafletMouseEvent, feature: any): boolean | undefined {
if (!this.settings.hover) return;
const result = this.settings.hover(e, feature);
Expand Down
21 changes: 21 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class Glify {
longitudeKey = 1;
latitudeKey = 0;
clickSetupMaps: Map[] = [];
contextMenuSetupMaps: Map[] = [];
hoverSetupMaps: Map[] = [];
shader = shader;

Expand Down Expand Up @@ -63,6 +64,7 @@ export class Glify {
points(settings: Partial<IPointsSettings>): Points {
const points = new this.Points({
setupClick: this.setupClick.bind(this),
setupContextMenu: this.setupContextMenu.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: glify.latitudeKey,
longitudeKey: glify.longitudeKey,
Expand All @@ -81,6 +83,7 @@ export class Glify {
lines(settings: Partial<ILinesSettings>): Lines {
const lines = new this.Lines({
setupClick: this.setupClick.bind(this),
setupContextMenu: this.setupContextMenu.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: this.latitudeKey,
longitudeKey: this.longitudeKey,
Expand All @@ -99,6 +102,7 @@ export class Glify {
shapes(settings: Partial<IShapesSettings>): Shapes {
const shapes = new this.Shapes({
setupClick: this.setupClick.bind(this),
setupContextMenu: this.setupContextMenu.bind(this),
setupHover: this.setupHover.bind(this),
latitudeKey: this.latitudeKey,
longitudeKey: this.longitudeKey,
Expand Down Expand Up @@ -130,6 +134,23 @@ export class Glify {
});
}

setupContextMenu(map: Map): void {
if (this.contextMenuSetupMaps.includes(map)) return;
this.clickSetupMaps.push(map);
map.on("contextmenu", (e: LeafletMouseEvent) => {
e.originalEvent.preventDefault(); // Prevent the default context menu from showing
let hit;
hit = this.Points.tryContextMenu(e, map, this.pointsInstances);
if (hit !== undefined) return hit;

hit = this.Lines.tryContextMenu(e, map, this.linesInstances);
if (hit !== undefined) return hit;

hit = this.Shapes.tryContextMenu(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);
Expand Down
83 changes: 83 additions & 0 deletions src/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,89 @@ export class Lines extends BaseGlLayer<ILinesSettings> {
}
}

// attempts to click the top-most Lines instance
static tryContextMenu(
e: LeafletMouseEvent,
map: Map,
instances: Lines[]
): boolean | undefined {
let foundFeature: Feature<LineString | MultiLineString> | null = null;
let foundLines: Lines | null = null;

instances.forEach((instance: Lines): void => {
const { latitudeKey, longitudeKey, sensitivity, weight, scale, active } =
instance;
if (!active) return;
if (instance.map !== map) return;
function checkContextMenu(
coordinate: Position,
prevCoordinate: Position,
feature: Feature<LineString | MultiLineString>,
chosenWeight: number
): void {
const distance = latLngDistance(
e.latlng.lng,
e.latlng.lat,
prevCoordinate[longitudeKey],
prevCoordinate[latitudeKey],
coordinate[longitudeKey],
coordinate[latitudeKey]
);
if (distance <= sensitivity + chosenWeight / scale) {
foundFeature = feature;
foundLines = instance;
}
}
instance.data.features.forEach(
(feature: Feature<LineString | MultiLineString>, i: number): void => {
const chosenWeight =
typeof weight === "function" ? weight(i, feature) : weight;
const { coordinates, type } = feature.geometry;
if (type === "LineString") {
for (let i = 1; i < coordinates.length; i++) {
checkContextMenu(
coordinates[i] as Position,
coordinates[i - 1] as Position,
feature,
chosenWeight
);
}
} else if (type === "MultiLineString") {
// TODO: Unit test
for (let i = 0; i < coordinates.length; i++) {
const coordinate = coordinates[i];
for (let j = 0; j < coordinate.length; j++) {
if (j === 0 && i > 0) {
const prevCoordinates = coordinates[i - 1];
const lastPositions =
prevCoordinates[prevCoordinates.length - 1];
checkContextMenu(
lastPositions as Position,
coordinates[i][j] as Position,
feature,
chosenWeight
);
} else if (j > 0) {
checkContextMenu(
coordinates[i][j] as Position,
coordinates[i][j - 1] as Position,
feature,
chosenWeight
);
}
}
}
}
}
);
});

if (foundLines && foundFeature) {
const result = (foundLines as Lines).contextMenu(e, foundFeature);
return result !== undefined ? result : undefined;
}
}

hoveringFeatures: Array<Feature<LineString | MultiLineString>> = [];
// hovers all touching Lines instances
static tryHover(
Expand Down
Loading

0 comments on commit 54a19a9

Please sign in to comment.