简体   繁体   中英

OpenLayers 3: stylefunction is not called for unselected features after zoom/pan

I've prepared a fiddle for my problem: Fiddle

  1. Click on a blue circle to select it -> it becomes red
  2. Click on the other blue circle -> the original becomes blue (deselected) and the new one becomes red (selected)

so far so good. Now if you instead do the following:

  1. Click on a blue circle -> it becomes red
  2. Zoom out and back in -> it stays red
  3. Click on the other blue circle

-> both circles are red instead of deselecting the first!

All I have is a selectInteraction with a styleFunction like this (I do some more things like text and caching the styles but the effect is the same):

function styleFunction(feature, resolution) {
    var selected = selectInteraction.getFeatures().getArray().indexOf(feature) >= 0;

    return [
    new ol.style.Style({
        image: new ol.style.Circle({
            radius: 30,
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 1
            }),
            fill: new ol.style.Fill({
                color: selected ? [255, 0, 0, 1] : [0, 0, 255, 1]
            })
        }),
        text: new ol.style.Text({
            text: 'Test',
            fill: new ol.style.Fill({
                color: 'black'
            })
        })
    })];
}

Why is my "deselected"-Style wrong after zooming or panning? As far as I can see when debugging the styleFunction the selection is correct (only contains 1 item), just the deselected item doesn't get styled correctly.

I use a styleFunction because no matter if selected or not, I'm setting the text and radius according to an object that is attached to the feature. So I calculate the style of a feature and I use the same styleFunction for selected and for deselected features.


Edit: Solution

I updated the Fiddle . Apparently you have to set the style of all deselected features to "null" (see Jonatas Walker's answer):

selectInteraction.on('select', function (evt) {
    if (evt) {
        $.each(evt.deselected, function (idx, feature) {
            feature.setStyle(null);
        });
    }
});

UPDATE - http://jsfiddle.net/jonataswalker/4vu669Lq/

Inside styleFunction

var fill_color = (this instanceof ol.Feature) ?
    [0, 0, 255, 1] : [255, 255, 255, 1];

And set the selected style on select listener:

selectInteraction.on('select', function(evt){
    var selected = evt.selected;
    var deselected = evt.deselected;
    if (selected.length) {
        selected.forEach(function(feature){
            feature.setStyle(styleFunction);
        });
    }
    if (deselected.length) {
        deselected.forEach(function(feature){
            feature.setStyle(null);
        });
    }
});

This is because you are using the same styleFunction for both ol.layer.Vector and ol.select.Interaction .

So when you zoom in/out the vector layer reads the style from your styleFunction .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM