1、前言
为了提升人机交互的体验,OpenLayers
提供了一系列的地图动画效果,它们主要由ol.animation
类提供,动画效果可以单独使用,也可以组合使用,下面开始介绍。
2、主要类和参数
在ol.animation
中,最常用到的四个类如下所示,它们分别对应平移
、弹跳
、旋转
、缩放
。
- ol.animation.pan
- ol.animation.bounce
- ol.animation.rotate
- ol.animation.zoom
要创建一个动画效果的步骤如下所示:
// 第一步:获取当前视图
var view = map.getView();
// 第二步:声明一个动画效果
var pan = new ol.animation.pan({...});
// 第三步:设置地图的beforeRender
map.beforeRender(pan);
// 第四步:设置当前视图的中心点
view.setCenter([121.43, 34.50]);
在设置动画效果的参数时需要明确各个参数的含义,常用的参数如下所示:
- duration:表示动画持续的时间
- source:表示移动的基准点
- easing:表示一个度,主要用于弹跳效果
- rotation:表示旋转的角度
- resolution:表示分辨率
- start:表示动画开始的时间
3、地图动画效果的实现
还是跟之前一样,我们构建一个简易的地图应用,如下图所示:
代码如下所示:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>OpenLayers</title>
<link href="lib/ol/ol.css" rel="stylesheet" />
<!-- openlayers -->
<script src="lib/ol/ol.js"></script>
<link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<!-- bootstrap -->
<script src="lib/bootstrap/js/jquery-3.4.1.min.js"></script>
<script src="lib/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div id="map" style="width:800px;height:600px"></div>
<div style="margin-top:20px;">
<button id="pan" class="btn btn-primary">平移</button>
<button id="elastic" class="btn btn-primary">弹跳</button>
<button id="bounce" class="btn btn-primary">反弹</button>
<button id="rotate" class="btn btn-primary">旋转</button>
<button id="pan_rotate" class="btn btn-primary">自旋转</button>
<button id="pan_bounce" class="btn btn-primary">飞行</button>
<button id="pan_bounce_rotate" class="btn btn-primary">自螺旋</button>
</div>
<script>
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
projection: 'EPSG:4326',
center: [120, 30],
zoom: 7
}),
loadTilesWhileAnimating: true,
})
// 平移
$('#pan').click(function () {
var view = map.getView();
var pan = new ol.animation.pan({
duration: 3000,
source: view.getCenter()
});
map.beforeRender(pan);
view.setCenter([116.42, 39.92]);
})
// 弹跳
$('#elastic').click(function () {
var view = map.getView();
var pan = new ol.animation.pan({
duration: 3000,
easing: elastic,
source: view.getCenter()
});
map.beforeRender(pan);
view.setCenter([121.43, 34.50]);
})
// 反弹
$('#bounce').click(function () {
var view = map.getView();
var pan = new ol.animation.pan({
duration: 3000,
easing: bounce,
source: view.getCenter()
});
map.beforeRender(pan);
view.setCenter([113.23, 23.17]);
})
// 旋转
$('#rotate').click(function () {
var view = map.getView();
var rotate = new ol.animation.rotate({
duration: 3000,
rotation: 2 * Math.PI
});
map.beforeRender(rotate);
view.setCenter([120.20, 30.27]);
})
// 自旋转
$('#pan_rotate').click(function () {
var view = map.getView();
var date = +new Date();
var pan = new ol.animation.pan({
duration: 3000,
source: view.getCenter(),
start: date
});
var rotate = new ol.animation.rotate({
duration: 3000,
rotation: 2 * Math.PI,
start: date
});
map.beforeRender(pan, rotate);
view.setCenter([114.32, 30.52]);
})
// 飞行
$('#pan_bounce').click(function () {
var view = map.getView();
var date = +new Date();
var pan = new ol.animation.pan({
duration: 3000,
source: view.getCenter(),
start: date
});
var bounce = new ol.animation.bounce({
duration: 3000,
resolution: 4 * view.getResolution(),
start: date
});
map.beforeRender(pan, bounce);
view.setCenter([117.17, 31.52]);
})
// 自螺旋
$('#pan_bounce_rotate').click(function () {
var view = map.getView();
var date = +new Date();
var pan = new ol.animation.pan({
duration: 3000,
source: view.getCenter(),
start: date
});
var bounce = new ol.animation.bounce({
duration: 3000,
resolution: 4 * view.getResolution(),
start: date
});
var rotate = new ol.animation.rotate({
duration: 3000,
rotation: 2 * Math.PI,
start: date
});
map.beforeRender(pan, bounce, rotate);
view.setCenter([118.10, 24.47]);
})
// 弹跳缓和方法
function bounce(t) {
var s = 7.5625, p = 2.75, l;
if (t < (1 / p)) {
l = s * t * t;
}
else {
if (t < (2 / p)) {
t -= (1.5 / p);
l = s * t * t + 0.75;
}
else {
if (t < (2.5 / p)) {
t -= (2.25 / p);
l = s * t * t + 0.9375;
}
else {
t -= (2.625 / p);
l = s * t * t + 0.984375;
}
}
}
return l;
}
// 弹性宽松方法
function elastic(t) {
return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;
}
</script>
</body>
</html>
4、结语
在上面的代码中需要注意两个地方,一个是var date = +new Date();
,这种写法主要是为了获取时间戳。第二个就是function bounce(t) { }
和function elastic(t) { }
这两个函数,其实大家不必纠结这两个函数到底是什么意思,你只需要知道它们就是用来计算弹性度的就可以了。如果你想深入了解这两个函数的意义,也可以访问http://www.robertpenner.com/easing/
进行学习。