Denilson Sá Maia
Denilson Sá Maia

Reputation: 49357

How to execute some code whenever the user interacts with the map?

I have an OpenLayers 3.9.0 map. I also have a pair of LonLat coordinates that I am tracking from an external source and updating onto the map. I am continuously re-centering the map on these coordinates:

function gets_called_when_I_have_updated_coords() {
    map.getView.setCenter(coords);
}

What I want is to disable this auto-centering whenever the user interacts with the map. In other words, I want this:

var auto_center = true;

function gets_called_when_I_have_updated_coords() {
    if (auto_center) {
        map.getView.setCenter(coords);
    }
}

function user_started_interacting() {
    auto_center = false;
}
// But where should this function be attached to?
// where.on('what?', user_started_interacting);

I don't know how to detect a user interaction.

I expected that the default interactions had some kind of event, so that when the user starts dragging/rotating/zooming the map, an event would be triggered and my code would run. I could not find such event.

Upvotes: 2

Views: 1650

Answers (3)

Denilson Sá Maia
Denilson Sá Maia

Reputation: 49357

As an workaround, I can attach an event to a change in the view:

map.getView().on('change:center', function(ev){…});

But I must take extra steps to distinguish from code-initiated changes from user-initiated ones. The complete code looks somewhat like this:

var auto_center = true;
var ignore_change_events = false;

function gets_called_when_I_have_updated_coords() {
    if (auto_center) {
        ignore_change_events = true;
        map.getView.setCenter(coords);
        ignore_change_events = false;
    }
}

map.getView().on('change:center', function() {
    if (ignore_change_events) {
        return;
    }
    auto_center = false;
});

Note that this approach breaks if any animation is used (and there is no callback or event for when an animation finishes).

Depending on your project, you may want to try either this solution or Jonatas Walker's solution.

Upvotes: 0

Jonatas Walker
Jonatas Walker

Reputation: 14150

Here, the user is dragging:

map.on('pointermove', function(evt){
    if(evt.dragging){
        //user interacting
        console.info('dragging');
    }
});

Here, the user is changing resolution:

map.getView().on('change:resolution', function(evt){
    console.info(evt);
});

UPDATE

Some options to detect keyboard interaction:

//unofficial && undocumented
map.on('key', function(evt){
    console.info(evt);
    console.info(evt.originalEvent.keyIdentifier);
});
//DOM listener
map.getTargetElement().addEventListener('keydown', function(evt){
    console.info(evt);
    console.info(evt.keyIdentifier);
});

A fiddle to test.

Upvotes: 2

Alexandre Dubé
Alexandre Dubé

Reputation: 2829

An other approach could be to listen to the pointerdown and pointerup events occurring on the map and while the down is in action, disable your auto-center feature.

map.on('pointerdown', function() {
  auto_center = false;
}, this);

map.on('pointerup', function() {
  auto_center = true;
}, this);

This approach may need more work, but it would be a start. Thoughts ?

Upvotes: 0

Related Questions