本博客合集是我的openlayers學(xué)習(xí)筆記,希望能幫助到剛開(kāi)始接觸openlayers的同學(xué)
@commnet 所用openlayers版本:v5.3.0
@commnet 閱讀本文前需要對(duì)前端知識(shí)有一定的了解
@comment 本文內(nèi)容只提供參考,建議結(jié)合openlayers官網(wǎng)的API和examples來(lái)學(xué)習(xí)
@comment 部分代碼參考了@老胡
動(dòng)畫即過(guò)渡動(dòng)畫,如果沒(méi)有動(dòng)畫,地圖從一個(gè)view狀態(tài)切換到另一個(gè)view狀態(tài)是突變的、死板的,動(dòng)畫能使過(guò)渡效果更自然。
本節(jié)內(nèi)容主要用到了view對(duì)象的animate方法,下面以實(shí)例說(shuō)明。
- 創(chuàng)建幾個(gè)功能測(cè)試按鈕和一個(gè)地圖容器
<button id="rotate-left" title="順時(shí)針旋轉(zhuǎn)">?</button>
<button id="rotate-right" title="逆時(shí)針旋轉(zhuǎn)">?</button>
<button id="pan-to-london">平移到倫敦</button>
<button id="elastic-to-moscow">彈性平移到莫斯科</button>
<button id="bounce-to-istanbul">彈跳平移到伊斯坦布爾</button>
<button id="spin-to-rome">旋轉(zhuǎn)平移到羅馬</button>
<button id="rotate-around-rome">繞著羅馬旋轉(zhuǎn)</button>
<button id="fly-to-bern">飛行到伯爾尼</button>
<button id="tour">來(lái)一段旅行</button>
<div id="map" class="map"></div>
- 創(chuàng)建地圖對(duì)象和幾個(gè)城市的偽墨卡托坐標(biāo)變量,還有一個(gè)為按鈕添加點(diǎn)擊事件的函數(shù),方便后續(xù)調(diào)用
var london = ol.proj.fromLonLat([-0.12755, 51.507222]);//倫敦
var moscow = ol.proj.fromLonLat([37.6178, 55.7517]);//莫斯科
var istanbul = ol.proj.fromLonLat([28.9744, 41.0128]);//伊斯坦布爾
var rome = ol.proj.fromLonLat([12.5, 41.9]);//羅馬
var bern = ol.proj.fromLonLat([7.4458, 46.95]);//柏林
var view = new ol.View({
center: istanbul,
zoom: 6
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
preload: 4,
source: new ol.source.OSM()
})
],
//開(kāi)啟動(dòng)畫時(shí)允許加載瓦片數(shù)據(jù)
loadTilesWhileAnimating: true,
view: view
});
function onClick(id, callback) {
document.getElementById(id).addEventListener('click', callback);
}
- 通過(guò)rotation參數(shù)設(shè)置地圖的旋轉(zhuǎn)動(dòng)畫
在animate中傳入想要變化的view的目標(biāo)參數(shù)(如rotation、center),從當(dāng)前狀態(tài)變化到目標(biāo)狀態(tài)時(shí),如不指定動(dòng)畫類型,地圖會(huì)使用默認(rèn)方式渲染動(dòng)畫。
onClick('rotate-left', function() {
//設(shè)置rotation參數(shù)的目標(biāo)值為當(dāng)前角度順時(shí)針加90度,地圖會(huì)以默認(rèn)方式渲染動(dòng)畫
view.animate({
rotation: view.getRotation() + Math.PI / 2
});
});
onClick('rotate-right', function() {
//設(shè)置rotation參數(shù)的目標(biāo)值為當(dāng)前角度順時(shí)針減90度,地圖會(huì)以默認(rèn)方式渲染動(dòng)畫
view.animate({
rotation: view.getRotation() - Math.PI / 2
});
});
- 入場(chǎng)動(dòng)畫和出場(chǎng)動(dòng)畫
地圖過(guò)渡的一段動(dòng)畫可以同時(shí)包括入場(chǎng)動(dòng)畫和出場(chǎng)動(dòng)畫,在同一animate函數(shù)中指定。下面的例子中,入場(chǎng)動(dòng)畫為先慢后快地以羅馬為中心、將地圖順時(shí)針旋轉(zhuǎn)180度,出場(chǎng)動(dòng)畫為先快后慢地以羅馬為中心、繼續(xù)順時(shí)針旋轉(zhuǎn)至360度。
onClick('rotate-around-rome', function() {
var rotation = view.getRotation();
view.animate(
//入場(chǎng)動(dòng)畫為順時(shí)針旋轉(zhuǎn)180度
{
rotation: rotation + Math.PI,
anchor: rome,//圍繞羅馬旋轉(zhuǎn)
easing: ol.easing.easeIn//擦除方式使用先慢后快的ol.easing.easeIn
},
//出場(chǎng)動(dòng)畫為順時(shí)針旋轉(zhuǎn)360度
{
rotation: rotation + 2 * Math.PI,
anchor: rome,
easing: ol.easing.easeOut//擦除方式使用先快后慢的ol.easing.easeOut
});
});
- 通過(guò)center參數(shù)設(shè)置地圖的移動(dòng)動(dòng)畫
下面的例子展示了地圖以默認(rèn)動(dòng)畫從當(dāng)前中心點(diǎn)平移到倫敦,動(dòng)畫過(guò)程2秒
onClick('pan-to-london', function() {
view.animate({
center: london,
duration: 2000
});
});
- 自定義動(dòng)畫
easing可以自定義過(guò)渡效果函數(shù),返回值為0-1之間的小數(shù),代表起點(diǎn)到終點(diǎn)的變化進(jìn)度。下面的例子先定義了一個(gè)彈跳動(dòng)畫函數(shù),并使用該函數(shù)讓地圖以彈跳動(dòng)畫從當(dāng)前中心點(diǎn)平移到倫敦,動(dòng)畫過(guò)程2秒
function elastic(t) {
return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;
}
onClick('elastic-to-moscow', function() {
view.animate({
center: moscow,
duration: 2000,
easing: elastic
});
});
- 綜合應(yīng)用1
下面的例子展示了地圖從當(dāng)前中心點(diǎn)旋轉(zhuǎn)、平移到羅馬,前半程為入場(chǎng)動(dòng)畫,后半程為出場(chǎng)動(dòng)畫
onClick('spin-to-rome', function() {
var center = view.getCenter();
view.animate({
center: [
center[0] + (rome[0] - center[0]) / 2,
center[1] + (rome[1] - center[1]) / 2
],
rotation: Math.PI,
easing: ol.easing.easeIn
}, {
center: rome,
rotation: 2 * Math.PI,
easing: ol.easing.easeOut
});
});
- 并發(fā)執(zhí)行
如果給一個(gè)過(guò)程設(shè)置了多個(gè)動(dòng)畫,他們都是并行執(zhí)行的。下面的動(dòng)畫類似于一只鳥的視角,從當(dāng)前中心點(diǎn)移動(dòng)到另一個(gè)中心點(diǎn)(動(dòng)畫1),并且前半程縮小視角、后半程回到原視角(動(dòng)畫2)。
function flyTo(location, done) {
var duration = 2000;
var zoom = view.getZoom();
var parts = 2;
var called = false;
function callback(complete) {
--parts;
if (called) {
return;
}
if (parts === 0 || !complete) {
called = true;
done(complete);
}
}
view.animate({
center: location,
duration: duration
}, callback);
view.animate({
zoom: zoom - 1,
duration: duration / 2
}, {
zoom: zoom,
duration: duration / 2
}, callback);
}
onClick('fly-to-bern', function() {
flyTo(bern, function() {});
});
- 綜合應(yīng)用2
下面的例子使用上面創(chuàng)建的“鳥視角飛躍函數(shù)”,在多個(gè)城市之間跳躍
function tour() {
var locations = [london, bern, rome, moscow, istanbul];
var index = -1;
function next(more) {
if (more) {
++index;
if (index < locations.length) {
var delay = index === 0 ? 0 : 750;
setTimeout(function() {
flyTo(locations[index], next);
}, delay);
} else {
alert('Tour complete');
}
} else {
alert('Tour cancelled');
}
}
next(true);
}
onClick('tour', tour);
本節(jié)測(cè)試用例的界面如下
