Skip to content

Commit

Permalink
Feature: Allow hover effects and route switching in non-interactive m…
Browse files Browse the repository at this point in the history
…ode (#217)

Add hoverable flag
  • Loading branch information
Fsss126 authored Jan 11, 2024
1 parent 6484c31 commit bbf6016
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 24 deletions.
22 changes: 21 additions & 1 deletion demo/src/examples/1 User Interaction.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
let map: maplibregl.Map | undefined = undefined;
let directions: MapLibreGlDirections | undefined = undefined;
let interactive = true;
let hoverable = false;
let routeSwitch = false;
let refreshOnMove = false;
function changeRefreshOnMove() {
Expand Down Expand Up @@ -48,7 +50,15 @@
let message;
$: if (directions) {
directions.interactive = interactive;
if (directions.hoverable !== hoverable) {
directions.hoverable = hoverable;
}
if (directions.interactive !== interactive) {
directions.interactive = interactive;
}
if (directions.allowRouteSwitch !== routeSwitch) {
directions.allowRouteSwitch = routeSwitch;
}
directions.on("fetchroutesend", (event) => {
if (event.data.code !== "Ok") {
Expand All @@ -72,6 +82,16 @@
<strong>Interactivity enabled</strong>
</label>

<label class="flex items-center gap-3">
<input type="checkbox" bind:checked={hoverable} disabled={!directions} />
<strong>Hover enabled</strong>
</label>

<label class="flex items-center gap-3 ml-5">
<input type="checkbox" bind:checked={routeSwitch} disabled={!directions || !hoverable} />
<strong>Route switch</strong>
</label>

<label class="flex items-center gap-3">
<input type="checkbox" bind:checked={refreshOnMove} on:click={changeRefreshOnMove} disabled={!directions} />
<strong>Update route while dragging</strong>
Expand Down
92 changes: 69 additions & 23 deletions src/directions/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,20 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
*/

this.map.getCanvas().style.cursor = "pointer";
this.map.dragPan.disable();

const highlightedWaypointIndex = this._waypoints.findIndex((waypoint) => {
if (this.interactive) {
this.map.dragPan.disable();
}

const highlightedWaypoint = this._waypoints.find((waypoint) => {
return waypoint.properties?.id === feature?.properties?.id;
});
const highlightedSnappoint = this.snappoints.find(
(snappoint) => snappoint.properties.waypointProperties?.id === highlightedWaypoint.properties.id,
);

this.highlightedWaypoints = [this._waypoints[highlightedWaypointIndex]];
this.highlightedSnappoints = [this.snappoints[highlightedWaypointIndex]];
this.highlightedWaypoints = [highlightedWaypoint];
this.highlightedSnappoints = [highlightedSnappoint];

if (this.highlightedWaypoints[0]?.properties) {
this.highlightedWaypoints[0].properties.highlight = true;
Expand Down Expand Up @@ -403,19 +409,22 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
*/

this.map.getCanvas().style.cursor = "pointer";
this.map.dragPan.disable();

if (this.hoverpoint) {
this.hoverpoint.geometry.coordinates = [e.lngLat.lng, e.lngLat.lat];
} else {
this.hoverpoint = this.buildPoint([e.lngLat.lng, e.lngLat.lat], "HOVERPOINT", {
departSnappointProperties: {
...JSON.parse(feature?.properties?.departSnappointProperties ?? "{}"),
},
arriveSnappointProperties: {
...JSON.parse(feature?.properties?.arriveSnappointProperties ?? "{}"),
},
});

if (this.interactive) {
this.map.dragPan.disable();

if (this.hoverpoint) {
this.hoverpoint.geometry.coordinates = [e.lngLat.lng, e.lngLat.lat];
} else {
this.hoverpoint = this.buildPoint([e.lngLat.lng, e.lngLat.lat], "HOVERPOINT", {
departSnappointProperties: {
...JSON.parse(feature?.properties?.departSnappointProperties ?? "{}"),
},
arriveSnappointProperties: {
...JSON.parse(feature?.properties?.arriveSnappointProperties ?? "{}"),
},
});
}
}

this.routelines.forEach((routeline) => {
Expand Down Expand Up @@ -786,7 +795,7 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
],
})[0];

if (this.configuration.sensitiveWaypointLayers.includes(feature?.layer.id ?? "")) {
if (this._interactive && this.configuration.sensitiveWaypointLayers.includes(feature?.layer.id ?? "")) {
/*
* If a waypoint is clicked, remove it.
*/
Expand All @@ -798,7 +807,7 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
if (~respectiveWaypointIndex) {
this._removeWaypoint(respectiveWaypointIndex, e);
}
} else if (this.configuration.sensitiveSnappointLayers.includes(feature?.layer.id ?? "")) {
} else if (this._interactive && this.configuration.sensitiveSnappointLayers.includes(feature?.layer.id ?? "")) {
/*
* If a snappoint is clicked, find its respective waypoint and remove it.
*/
Expand All @@ -810,7 +819,10 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
if (~respectiveWaypointIndex) {
this._removeWaypoint(respectiveWaypointIndex, e);
}
} else if (this.configuration.sensitiveAltRoutelineLayers.includes(feature?.layer.id ?? "")) {
} else if (
(this.interactive || this.allowRouteSwitch) &&
this.configuration.sensitiveAltRoutelineLayers.includes(feature?.layer.id ?? "")
) {
/*
* If an alternative route line is clicked, set its index as the selected route's one.
*/
Expand All @@ -820,7 +832,7 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
return segment.properties?.id === feature?.properties?.id;
});
});
} else if (!this.configuration.sensitiveRoutelineLayers.includes(feature?.layer.id ?? "")) {
} else if (this._interactive && !this.configuration.sensitiveRoutelineLayers.includes(feature?.layer.id ?? "")) {
/*
* If the selected route line is clicked, don't add a new waypoint. Else do.
*/
Expand Down Expand Up @@ -921,18 +933,51 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
if (interactive) {
this.map.on("touchstart", this.onMoveHandler);
this.map.on("touchstart", this.onDragDownHandler);
this.map.on("mousemove", this.onMoveHandler);
this.map.on("mousedown", this.onDragDownHandler);
this.map.on("click", this.onClickHandler);

if (!this.hoverable) {
this.map.on("mousemove", this.onMoveHandler);
this.map.on("click", this.onClickHandler);
}
} else {
this.map.off("touchstart", this.onMoveHandler);
this.map.off("touchstart", this.onDragDownHandler);
this.map.off("mousemove", this.onMoveHandler);
this.map.off("mousedown", this.onDragDownHandler);

if (!this.hoverable) {
this.map.off("mousemove", this.onMoveHandler);
this.map.off("click", this.onClickHandler);
}
}
}

/**
* Allows hover effects in non-interactive mode. Can be set to `true` while `interactive` is `false` for the features
* to be highlighted when hovered over by the user. Does nothing when `interactive` is `true`.
*/
get hoverable() {
return this._hoverable;
}

set hoverable(hoverable) {
this._hoverable = hoverable;

if (hoverable && !this.interactive) {
this.map.on("mousemove", this.onMoveHandler);
this.map.on("click", this.onClickHandler);
} else if (!this.interactive) {
this.map.off("mousemove", this.onMoveHandler);
this.map.off("click", this.onClickHandler);
}
}

/**
* Allows user to switch to alternative routes while in non-interactive mode. Only takes effect when `hoverable` is
* `true`.
*/
public allowRouteSwitch = false;

/**
* Returns all the waypoints' coordinates in the order they appear.
*/
Expand Down Expand Up @@ -1092,6 +1137,7 @@ export default class MapLibreGlDirections extends MapLibreGlDirectionsEvented {
this.abortController?.abort("DESTROY");

this.clear();
this.hoverable = false;
this.interactive = false;

this.configuration.layers.forEach((layer) => {
Expand Down

0 comments on commit bbf6016

Please sign in to comment.