Skip to content

Commit

Permalink
Link pointer when hovering over clickable feature in map. (#1292)
Browse files Browse the repository at this point in the history
* #1259 Added link pointer when hovering over clickable feature in map.

* #1259 Changed requirement for pointer to not require separate classes for layers and replaced with a shared class for all clickable layers.

Also renamed option to changePointerOnHover.

* #1259 Lint...

Co-authored-by: Stefan Forsgren <stefan@forsgren@xlent.se>
  • Loading branch information
steff-o and Stefan Forsgren authored Sep 2, 2021
1 parent 10349ff commit 96dddd1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/featureinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,29 @@ const Featureinfo = function Featureinfo(options = {}) {
setActive(false);
}
});

// Change mouse pointer when hovering over a clickable feature
if (viewer.getViewerOptions().featureinfoOptions.changePointerOnHover) {
let pointerActive = true;
document.addEventListener('enableInteraction', evt => {
pointerActive = evt.detail.interaction !== 'editor';
// Avoid getting stuck in pointer mode if user manages to enable editing while having pointer over a clickable feature.
// If the user manages to disable editing while standing on a clickable feature, it will remain arrow until moved. (Sorry)
map.getViewport().style.cursor = '';
});

// Check if there is a clickable feature when mouse is moved.
map.on('pointermove', evt => {
if (!pointerActive || evt.dragging) return;
// Just check if there is a pixel here. Pretty annoying on hatched symbols or hollow areas.
// Note that forEachLayerAtPixel actually only checks if there is a pixel on the canvas where the layer resides,
// so non queryable layers must not share canvas with queryable layers, otherwise there will be false positives.
// When a pixel is found on the canvas, the callback is called with all layers added to that canvas as it does not know which layer actually draw a pixel there. But we don't care which
// layer was hit to change the pointer.
// Hit tolerence seems to be ignored. It would probably look funny anyway.
map.getViewport().style.cursor = map.forEachLayerAtPixel(evt.pixel, () => true, { layerFilter: (l) => l.get('queryable') }) ? 'pointer' : '';
});
}
},
render
});
Expand Down
12 changes: 12 additions & 0 deletions src/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ const Layer = function Layer(optOptions, viewer) {
layerOptions.className = layerOptions.cls || `o-layer-${layerOptions.name}`;
}

// changePointerOnHover requires that non queryable layers are not drawn on the same canvas as queryable layers.
// OL will merge layers to the same canvas if they have the same class and some other reconcilable properties.
// Note that the merge preserves layer ordering, so if a layer can not use same canvas as previous layer, a new
// canvas will be created, so keep layers with same properties together.
// Make sure that queryable layers get a class name to avoid merging with non queryable layers.
// A unique class would be best, but produces a new canvas for each layer, which could affect the
// performance.
// If user has configured a className then keep it and let the user take the consequences if they mix queryable and non queryable layers.
if (viewer.getViewerOptions().featureinfoOptions.changePointerOnHover && layerOptions.queryable && !layerOptions.className) {
layerOptions.className = 'o-layer-queryable';
}

if (layerOptions.type) {
const layer = type[layerOptions.type](layerOptions, viewer);
layer.once('postrender', onChangeVisible);
Expand Down

0 comments on commit 96dddd1

Please sign in to comment.