OpenLayers基础教程——地图的动画效果

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/进行学习。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值