Le ultime versioni di OpenLayers hanno notevolmente semplificato l’utilizzo delle funzioni per muovere la mappa ad una determinata posizione e cambiarne i livelli di zoom, anche con animazioni per rendere la transizioni più morbide e piacevoli. Il controllo della posizione e del livello di zoom viene operatore dalla ol.View associata alla mappa, la quale espone i metodi per gestirne i valori e le modalità di transizione:

  • ol.View.animate: tramite le varie opzioni che si possono definire possiamo controllare la transizione verso una determinata coordinata e/o un certo livello di zoom/risoluzione
  • ol.View.fit: con questo metodo possiamo far sì che la mappa si adatti alla geometria o all’extent passato come argomento della funzione

In questo primo esempio vediamo come poter realizzare un effetto “fly to”, ovvero un pan abbinato ad un effetto di zoom in e zoom out.

  1. A riga 6 registro una prima animazione definendo le opzioni coordinate e duration. Il metodo vedrà che gli ho fornito una coordinata e quindi avvierà un pan con un’animazione della durata di 1000ms (riga 20).
  2. Subito dopo, a riga 11, registro un’altra animazione. La precedente animazione è appena iniziata, ma subito ne aggiungo un’altra, per cui le due animazioni saranno eseguite (praticamente) in contemporanea. Questa seconda animazione è, in realtà, composta da due animazioni sequenziali:

    1. Nel primo passo definisco l’opzione zoom, con valore unitario inferiore a quello attuale (riga 4). L’effetto sarà uno zoom out con una durata pari a metà di quella totale
    2. Nel secondo passo faccio l’operazione contraria, ovvero torno allo zoom iniziale, sempre con durata metà di quella totale

L’effetto globale sarà un pan e una sequenza zoom out / zoom in eseguiti in contemporanea.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var coordinate = [1158011.77434,5421736.70942];
var view = map.getView();
duration = 1000;
var zoom = view.getZoom();

view.animate({
    center: coordinate,
    duration: duration
});

view.animate(
{
  zoom: zoom - 1,
  duration: duration / 2
}, {
  zoom: zoom,
  duration: duration / 2
});

In questi esempi non abbiamo considrato l’opzione easing, ovvero la funzione che calcola i valori delle variabile dell’animazione nel tempo (coordinate, risoluzione, ecc.). Di default viene usata la funzione ol.easing.inAndOut, che ha l’effetto di iniziare lentamente, raggiungere la massima velocità a metà dell’animazione, per poi decelerare di nuovo fino al termine. Ne esistono altre, tra cui una lineare ol.easing.linear, ma volendo è possibile definire la propria funzione, che sarà chiamata ad ogni frame dell’animazione.

Vediamo adesso come fare per adattare la mappa ad una geometria o ad un’estensione. In questo caso useremo lo.View.fit, che si aspetta come primo parametro obbligatorio una geometria o un extent. Questa funzione è specifica per eseguire, di fatto, pan e zoom all’estensione richiesta, per cui ha meno opzioni rispetto a ol.View.animate.

  • Di default, non è animata. Per attivare l’animazione dobbiamo definire una durata (che di base è 0ms).
  • Ancora, di default, la vista si adatta al livello di zoom più vicino a quello esatto per racchiudere perfettamente il BBOX della geometria/estensione. Impostando constrainResolution a false chiediamo invece alla vista di adattarsi precisamente alla geometria richiesta.
  • Ok, la vista sarà perfettamente adattata, ma visivamente è meglio se lasciamo un margine visuale minimo tra i bordi della mappa e la nostra geometria. Per farlo possiao usare l’opzione padding che imposterà, appunto, un padding superiore, destro, inferiore e sinistro (in pixel) tra la vista e la geometria richiesta.
1
2
3
4
5
6
var extent = [1123172.31556,5265613.41694,1165805.26613,5295243.54411];
map.getView().fit(extent, {
    duration: 1000,
    constrainResolution: false,
    padding: [10,10,10,10]
});

Anche per ol.View.fit è possibile definire l’opzione di easing che, anche in questo caso, è impostata di base a ol.easing.inAndOut.