web-dev-qa-db-fra.com

Comment changer le curseur en survol dans Openlayers 3?

J'ai réussi à ajouter de l'interactivité à une couche d'entités ajoutée à partir d'une ressource GeoJSON distante. Lorsque je clique sur une entité, je reçois son identifiant, envoie une requête AJAX et affiche des informations pertinentes sur l'entité sur la page située en dehors de la zone de carte.

J'ai utilisé une interaction Select.

Je tiens à préciser encore plus à l'utilisateur qu'il peut cliquer sur les éléments de la carte. Est-il possible de changer le curseur de la souris en "curseur" de "main" lorsque la souris survole une caractéristique contenue dans un ol.layer.Vector?

Je n'ai rien trouvé dans la doc, sur ce site ou sur Google.

15
Pierre Henry

Grâce au lien d'exemple fourni par Azathoth dans les commentaires, j'ai trouvé une solution:

  • using OL3 pointermove event
  • utiliser jQuery pour obtenir l'élément cible et changer le style de son curseur

Voici le code:

var cursorHoverStyle = "pointer";
var target = map.getTarget();

//target returned might be the DOM element or the ID of this element dependeing on how the map was initialized
//either way get a jQuery object for it
var jTarget = typeof target === "string" ? $("#"+target) : $(target);

map.on("pointermove", function (event) {
    var mouseCoordInMapPixels = [event.originalEvent.offsetX, event.originalEvent.offsetY];

    //detect feature at mouse coords
    var hit = map.forEachFeatureAtPixel(mouseCoordInMapPixels, function (feature, layer) {
        return true;
    });

    if (hit) {
        jTarget.css("cursor", cursorHoverStyle);
    } else {
        jTarget.css("cursor", "");
    }
});

Voici le lien vers l'exemple sur le site OpenLayers: http://openlayers.org/en/v3.0.0/examples/icon.html

9
Pierre Henry

Si cela ne fonctionne pas, essayez une combinaison des 2, semble fonctionner pour mon vecteur popup ...

var target = map.getTarget();
var jTarget = typeof target === "string" ? $("#" + target) : $(target);
// change mouse cursor when over marker
$(map.getViewport()).on('mousemove', function (e) {
    var pixel = map.getEventPixel(e.originalEvent);
    var hit = map.forEachFeatureAtPixel(pixel, function (feature, layer) {
        return true;
    });
    if (hit) {
        jTarget.css("cursor", "pointer");
    } else {
        jTarget.css("cursor", "");
    }
});
13
ohjeeez

Cela peut être fait aussi bien sans jQuery: 

map.on("pointermove", function (evt) {
    var hit = this.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
        return true;
    }); 
    if (hit) {
        this.getTarget().style.cursor = 'pointer';
    } else {
        this.getTarget().style.cursor = '';
    }
});
12
Pablo

Voici une autre façon de le faire:

map.on('pointermove', function(e){
  var pixel = map.getEventPixel(e.originalEvent);
  var hit = map.hasFeatureAtPixel(pixel);
  map.getViewport().style.cursor = hit ? 'pointer' : '';
});
10
Robert M

Pour moi cela a fonctionné comme ceci:

map.on('pointermove', function(e) {
          if (e.dragging) return;
          var pixel = e.map.getEventPixel(e.originalEvent);
          var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
              return true;
          });
          e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        });

J'ai aussi ajouté un filtre de calque:

map.on('pointermove', function(e) {
      if (e.dragging) return;
      var pixel = e.map.getEventPixel(e.originalEvent);
      var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
          return layer.get('name') === 'myLayer';
      });
      e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
    });

Je devais choisir une nouvelle solution car l'ancienne solution que je utilisais auparavant pour le filtre de calque ne fonctionnait plus:

var hit = e.map.hasFeatureAtPixel(e.pixel, function(layer){
             return layer.get('name') === 'myLayer';
          });
4
joschi81

Je l'ai fait avec le code suivant:

var target = $(map.getTargetElement()); //getTargetElement is experimental as of 01.10.2015
map.on('pointermove', function (evt) {
    if (map.hasFeatureAtPixel(evt.pixel)) { //hasFeatureAtPixel is experimental as of 01.10.2015
        target.css('cursor', 'pointer');
    } else {
        target.css('cursor', '');
    }
});
2
NoRyb

Un moyen simple d'obtenir un élément cible 

var target = map.getTarget();

target = typeof target === "string" ?
    document.getElementById(target) : target;

target.style.cursor = features.length > 0) ? 'pointer' : '';
1
Nurlan

Si vous utilisez Angular 2, vous devez utiliser le code suivant:

this.map.on("pointermove", function (evt) {
    var hit = evt.map.hasFeatureAtPixel(evt.pixel);
    this.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

Si la variable map est une classe de membre, vous la désignerez sous le nom "this.map". Si elle est déclarée à l'intérieur de la fonction actuelle, elle peut être appelée "map". Mais surtout, vous n'écrivez pas

map.getTargetElement()

mais vous écrivez

this.getTargetElement()
1
nix86

Uncaught TypeError: Cannot set property 'cursor' of undefined.

Corrigé avec: map.getTargetElement()s.style.cursor = hit ? 'pointer' : ''; au lieu de map.getTarget().style.cursor = hit ? 'pointer' : '';

1
cinthyasm

J'ai essayé de minimiser la clôture de pointermove, en évitant de mettre à jour le style quand ce n'est pas nécessaire, parce qu'il appelle très souvent:

Exemple-1: utilise jQuery :

var cursorStyle = "";
map.on("pointermove", function (e) {
    let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
    newStyle !== cursorStyle && $(this.getTargetElement()).css("cursor", cursorStyle = newStyle);
});

Exemple-2: non jQuery:

var cursorStyle = "";
map.on("pointermove", function (e) {
    let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
    if (newStyle !== cursorStyle) {
        this.getTargetElement().style.cursor = cursorStyle = newStyle;
    }
});
0
AamirR

Une autre manière (combinée à partir de parties des réponses ci-dessus, mais encore plus simple):

map.on("pointermove", function (evt) {
    var hit = map.hasFeatureAtPixel(evt.pixel);
    map.getTargetElement().style.cursor = (hit ? 'pointer' : '');
});
0
JustAC0der