动画高阶应用
虽然内置动画并不多,但是细心的同学已经发现了内置动画有个参数easing
,这是一个强大的参数,因为可以让开发者自定义动画实现,从而实现动画效果的扩展。 其实已经内置了一些相关的实现,在ol.easing
里面,涉及到一些常用的效果,包括:
ol.easing.easeIn
: 加速ol.easing.easeOut
: 减速ol.easing.inAndOut
: 先加速再减速ol.easing.linear
: 匀速ol.easing.upAndDown
: 和inAndOut类似
在前面的地图的基础上修改一下,让大家体验一下不同的动画的效果:
尝试完所有的动画方式后,可以看一下其实现代码:
<div id="map" style="width: 100%"></div>
<!--添加动画效果选择项-->
<select id = "easing-type">
<option>easeIn</option>
<option>easeOut</option>
<option>inAndOut</option>
<option>linear</option>
<option>upAndDown</option>
</select>
<input type="button" value="回到原点" onclick="backWithAnim()"></input>
<script type="text/javascript">
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
})
});
// 根据选择项,返回对应的动画,供下面的backWithAnim函数使用
function getEasing() {
var typeSelect = document.getElementById('easing-type');
var easing = typeSelect.options[typeSelect.selectedIndex].text;
if (easing === 'easeIn') {
return ol.easing.easeIn;
} else if (easing === 'easeOut') {
return ol.easing.easeOut;
} else if (easing === 'inAndOut') {
return ol.easing.inAndOut;
} else if (easing === 'linear') {
return ol.easing.linear;
} else if (easing === 'upAndDown') {
return ol.easing.upAndDown;
}
}
function backWithAnim() {
var pan = ol.animation.pan({
duration: 2000,
source: map.getView().getCenter(),
easing: getEasing() // 设置对应选择的动画
});
map.beforeRender(pan);
map.getView().setCenter(ol.proj.transform([104, 30], 'EPSG:4326', 'EPSG:3857'));
}
</script>
通过上面这种方法,我们完全可以自定义动画函数,通过官网API文档可知,这些函数有一个参数t
,范围在0-1之间,然后函数返回一个0-1之间的数。 结合动画业务来看,虽然官网没有说明参数表示什么意思,但是我们可以猜测它就是时间,返回的值应该目标达成比。 下面我们自己来实现一个sin曲线式的动画:
速度一开始会快一点,然后慢下来, 对应的代码如下:
<div id="map2" style="width: 100%"></div>
<input type="button" value="回到原点" onclick="backWithAnim2();"></input>
<script type="text/javascript">
var map2 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map2',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
})
});
// sin曲线动画
function sin(t) {
// 使用sin曲线公式
return Math.sin(t * Math.PI / 2);
}
function backWithAnim2() {
var pan = ol.animation.pan({
duration: 2000,
source: map2.getView().getCenter(),
easing: sin // 应用sin曲线动画
});
map2.beforeRender(pan);
map2.getView().setCenter(ol.proj.transform([104, 30], 'EPSG:4326', 'EPSG:3857'));
}
</script>