Search code examples
javascriptcontrolsopenlayersswipelayer

Layers in select interaction with swipe in openlayers


I use a swipe in Openlayers to show a layer on each side, which can be chosen from a menu. That is, it is not fixed whether a layer will be shown on the right or left side of the swipe. I have two select ol.interaction.Select: right and left side. My question is: how to dynamically change the layers for each select? In the code, layer1 is fixed to `selectPointerMove_left, but it may be that at some point, this layer will be added on side right.

var selectPointerMove_left = new ol.interaction.Select({
    condition: function(e) {
      return (
        ol.events.condition.pointerMove(e) &&
        e.pixel[0] < map.getSize()[0] * swipe_control.get('position')
      );
    },
    multi: false,
    layers: [layer1],
    style: selectedStyle
});

var selectPointerMove_right = new ol.interaction.Select({
    condition: function(e) {
      return (
        ol.events.condition.pointerMove(e) &&
        e.pixel[0] > map.getSize()[0] * swipe_control.get('position')
      );
    },
    multi: false,
    layers: [layer2],
    style: selectedStyle
}); 

Solution

  • Define a swapped boolean, if you swap the layers set it true and test in the select conditions:

    var swapped = false;
    
    var selectPointerMove_left = new ol.interaction.Select({
      condition: function (e) {
        return (
          ol.events.condition.pointerMove(e) &&
          (swapped
            ? e.pixel[0] > map.getSize()[0] * swipe_control.get('position')
            : e.pixel[0] < map.getSize()[0] * swipe_control.get('position'))
        );
      },
      multi: false,
      layers: [layer1],
      style: selectedStyle
    });
    
    var selectPointerMove_right = new ol.interaction.Select({
      condition: function (e) {
        return (
          ol.events.condition.pointerMove(e) &&
          (swapped
            ? e.pixel[0] < map.getSize()[0] * swipe_control.get('position')
            : e.pixel[0] > map.getSize()[0] * swipe_control.get('position'))
        );
      },
      multi: false,
      layers: [layer2],
      style: selectedStyle
    });
    

    Or for more complex cases than a simple swap you could replace the layers array with a filter function and a maintain left/right flag for each layer (or even a three way left/right/both flag where both would be valid for both interactions):

    var selectPointerMove_left = new ol.interaction.Select({
        condition: function(e) {
          return (
            ol.events.condition.pointerMove(e) &&
            e.pixel[0] < map.getSize()[0] * swipe_control.get('position')
          );
        },
        multi: false,
        filter: function(feature, layer) {
          return (
            {layer === layer1 && layer1Left) ||
            {layer === layer2 && layer2Left)
          );
        },
        style: selectedStyle
    });
    
    var selectPointerMove_right = new ol.interaction.Select({
        condition: function(e) {
          return (
            ol.events.condition.pointerMove(e) &&
            e.pixel[0] > map.getSize()[0] * swipe_control.get('position')
          );
        },
        multi: false,
        filter: function(feature, layer) {
          return (
            {layer === layer1 && !layer1Left) ||
            {layer === layer2 && !layer2Left)
          );
        },
        style: selectedStyle
    });