OpenLayers 3: събитие movestart на картата

OpenLayers3 API има map.on("moveend") , но не мога да намеря movestart. Някой знае ли как мога да постигна това? Има ли еквивалентно събитие?

OpenLayers 2 имаше movestart събитие на картата. Търся точен паралел в OpenLayers3

Ето основен jsFiddle. Ако някой иска да си поиграем. Добавих събитие movestart там, за да покажа какво искам, но мисля, че всъщност не съществува.

Случай на употреба! някой може да попита: имам спирки на карти, които имат информационни прозорци почти на цял екран. Потребителите могат да превключват към следващия маркер от информационния прозорец. Правя прозорците полупрозрачни, за да покажа картата, която се движи отдолу, така че потребителите да получат контекст къде е следващото местоположение. Тази работа е страхотна в OpenLayers2 с movestart и moveend събития. Но в новата OL3 версия на картата не мога да получа събитието movestart.

Актуализация: Аз сам отговорих на въпроса, но все още предлагам награда, ако някой иска да предложи по-добро решение.


person Shaunak    schedule 08.08.2015    source източник
comment
Какво не е наред с вашето собствено решение?   -  person Jonatas Walker    schedule 11.08.2015
comment
Кодът просто мирише. Това може да е нещо много просто, ако се поддържа обратното извикване. Всеки лесен начин за инжектиране на такова обратно извикване в библиотеката OL3 би бил добър отговор. Или това, или просто търся някои различни гледни точки тук, предполагам.   -  person Shaunak    schedule 11.08.2015
comment
Предполагам, че трябва да използвате събитието precompose. Вижте моя jsFiddle: jsfiddle.net/j2cP4/116   -  person GuyT    schedule 18.08.2015
comment
не можете ли просто да се преструвате, че третирате това като платно и да откриете събитието mousedown? Като този? (проверете конзолата): jsfiddle.net/j2cP4/117   -  person briosheje    schedule 18.08.2015
comment
@GuyT, не мога да използвам precompose, тъй като не е специално насочен за движение. Ще се задейства за всякакъв вид изобразяване на карта, като напр. промяна на слоя.   -  person Shaunak    schedule 20.08.2015
comment
Имате нужда от това за historyControl. Използването на масив от състояния на moveend е болка.   -  person milovanderlinden    schedule 28.10.2015


Отговори (2)


АКТУАЛИЗАЦИЯ v4.2.0 вече поддържа собствени събития movestart и moveend

map.on('movestart', function(event) {

    //To Remove after first use: ol.Observable.unByKey(event);
});

map.on('moveend', function(event) {

    //To Remove after first use:  ol.Observable.unByKey(event);
});

За версии на OpenLayers 3 преди пускането на v4.2.0

Добре, така че междувременно без събитието movestart и със задействането на moveend само ако има действително движение в картата, ето как успях да постигна поведение movestart и moveend.

jsFiddle:

var pan = ol.animation.pan({
    duration: 700,
    source: this.map.getView().getCenter()
});
map.beforeRender(function(map, frameState) {
    var stillPanning = pan(map, frameState); // returns false panning is done
    if (stillPanning) {
        // do movestart stuff here
        if (!everDone) {
            doSomething();
            everDone = true;
        }
    } else {
        // do move end stuff here
        undoSomething();
        everDone = false;
    }
    return stillPanning;
});
map.getView().setCenter(geom);

Така че защо това работи?

  1. ol.animation.pan връща ol.PreRenderFunction, което връща false if анимация не е пълна

  2. Писането на персонализирана функция и предоставянето й на map.renderBefore вече може да се използва за писане на обвивка около панорамна анимация, както е показано по-горе

  3. Цялата работа с everDone е, защото разделът stillPanning ще бъде извикан многократно. Това е добре, ако това, което искате да правите там, може да приеме многократни обаждания, но ако искате да превключите нещо, тогава искате да го направите само веднъж.

поведение на 'moveend' moveend обратното извикване се задейства само ако картата действително се премести. Това е добре, но ни пречи да извършваме дейности преди анимация, като просто ги правим преди анимацията да е готова. Ако сте имали сценарий, при който картата всъщност не се движи, тогава това, което сте правили преди анимацията, никога няма да undo, защото това поведение е в moveend, което никога не се извиква!

Надявам се това да помогне на някого. Трябваше да отделя добри два часа, за да го накарам да работи за мен, защото обратно извикване movestart липсва :(

АКТУАЛИЗИРАНЕ

След повече дискусии в тази нишка има друго решение, предложено от @ahocevar. Това означава да използвате събитието propertychange в изгледа по следния начин:

function onpropertychange() {
  map.dispatchEvent('movestart');
  var view = map.getView();
  view.un('propertychange', onpropertychange);
  map.on('moveend', function() {
    view.on('propertychange', onpropertychange);
  });
};
map.getView().on('propertychange', onpropertychange);

Ето един работещ пример за този подход: jsFiddle

person Shaunak    schedule 08.08.2015

можете да използвате събитието pointerdrag или pointermove, но ще искате да ги откажете. Направих го тук с променлива, наречена dragStarted

http://jsfiddle.net/sean9999/j2cP4/115/

http://openlayers.org/en/v3.8.2/apidoc/ol.MapBrowserEvent.html

person code_monk    schedule 18.08.2015
comment
Добре, но проблемът с този подход е, че зависи от действията на мишката. Не това преследвам. Openlayers могат да бъдат направени програмно да се движат или мащабират и тогава обратните извиквания са най-полезни. Това обаче е доста добър подход за хора, които искат да използват действията на мишката върху картата. - person Shaunak; 20.08.2015