OpenLayers加载常用控件(八)

注:当前使用的是 ol 「5.3.0」 版本,天地图使用的key请到天地图官网申请,并替换为自己的key

地图控件是一些用来与地图进行简单交互的工具,地图库预先封装好,可以供开发者直接使用。OpenLayers具有大部分常用的控件,如「缩放、导航、鹰眼、比例尺、旋转、鼠标位置」等。这些控件都是基于 ol.control.Control基类进行封装的,可以通过Map对象的controls属性或者调用addControl方法添加到地图中。地图控件通过HTML插入到Map页面,可以利用CSS调整地图控件样式。OpenLayers初始化地图时利用ol.control.default默认加载了缩放控件(ol.control.Zoom

本节主要介绍「动画控件」

1. 动画控件

动画控件可用于增强地图的动感效果,带给用户轻松的交互体验,适当的动画效果有利于增加地图体验。本节在原有地图方法上实现「旋转定位、弹性定位、反弹定位、自旋转定位、飞行定位」等效果。

1.1. 创建动画事件按钮

通过点击定位按钮开启动画。

<div class="animate-div">
  <button class="animate-btn" id="rotate-to">旋转定位到武汉</button>
  <button class="animate-btn" id="flex-to">弹性定位到北京</button>
  <button class="animate-btn" id="bounce-to">反弹定位到广州</button>
  <button class="animate-btn" id="rotate">围绕西安旋转</button>
  <button class="animate-btn" id="fly-to">飞行定位到杭州</button>
</div>

设置按钮CSS样式

.animate-div{
  position: relative;
  margin: 0 auto;
  padding: 20px;
  text-align: center;
}
.animate-btn{
  padding: 5px 10px;
  border-radius: 5px;
  font-size: 16px;
  color: #fff;
  background: #000000a1;
}

1.2. 创建定位点

分别定义城市坐标点

// 定位点坐标
const wuhan = ol.proj.fromLonLat([114.302387, 30.591255])
const beijing = ol.proj.fromLonLat([116.400739, 39.913359])
const guangzhou = ol.proj.fromLonLat([113.261081, 23.151553])
const xian = ol.proj.fromLonLat([108.951639, 34.351322])
const hangzhou = ol.proj.fromLonLat([120.205736, 30.253831])

1.3. 创建动画控制函数

// 获取反弹值
function bounce(t) {
    const s = 7.5625
    const p = 2.75
    let l = null
    if (t < l / 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) + 1
}

1.4. 创建定位事件函数

分别创建定位事件函数。

// 旋转定位
document.getElementById('rotate-to').onclick = function () {
    const center = view.getCenter()
    view.animate({
        // 第一个过程
        // 动画结束时的视图中心,即当前视图中心与目标视图中心连线的中心点
        center: [
            center[0] + (wuhan[0] - center[0]) / 2,
            center[1] + (wuhan[1] - center[1]) / 2
        ],
        rotation: Math.PI,// 动画结束时的旋转角度,即180度
        easing:ol.easing.easeIn // 控制动画速度,开始缓慢之后逐渐加快
    }, {
        // 第二个过程
        center: wuhan,// 动画结束时的视图中心
        rotation: 2*Math.PI,// 动画结束时的旋转角度,即360度
        easing: ol.easing.easeIn // 控制动画速度,开始缓慢之后逐渐加快
    })
}

//弹性伸缩效果定位
document.getElementById('flex-to').onclick = function () {
    view.animate({
        center: beijing,
        duration: 2000,//动画持续时间,单位为毫秒(ms)
        easing:elastic // 控自动画持续时间函数
    })
}
// 反弹效果定位
document.getElementById('bounce-to').onclick = () => {
    view.animate({
        center: guangzhou,
        duration: 2000,
        easing:bounce // 控制动画持续时间函数
    })
}
// 自旋效果定位
document.getElementById('rotate').onclick = ()=> {
    const rotation = view.getRotation()
    view.animate({
        // 第一个过程
        rotation: rotation + Math.PI, // 第一次动画旋转角度
        anchor: xian,// 自旋中心点
        easing: ol.easing.easeIn // 控自动画持续时间函数
    }, {
        // 第二个过程
        rotation: rotation + 2*Math.PI, // 第二次动画旋转角度
        anchor: xian,// 自旋中心点
        easing: ol.easing.easeOut// 控自动画持续时间函数
    })
}
// 飞行效果定位
document.getElementById('fly-to').onclick = () => {
    const duration = 2000 //动画持续时间,单位为毫秒(ms)
    const zoom = view.getZoom()
    let parts = 2
    let called = false
    // 动画完成的回调函数
    function callback(complete) {
        --parts
        if (called) {
            return
        }
        if (parts === 0 || !complete) {
            called = true
        }    
    }
    // 第一个动画
    view.animate({
        center: hangzhou,
        duration: duration,
        
    }, callback)
    // 第二个动画
    view.animate({
        zoom: zoom -1 ,
        duration: duration/2,
    }, {
        zoom: zoom,
        duration:duration / 2
    },callback)
}

2. View属性Animate参数介绍

参数名

类型

简介

center

ol.Coordinate

动画结束时的视图中心点

zoom

number

动画结束时的视图缩放级别

resolution

number

动画结束时的视图分辨率,如果设置了zoom参数,则该参数将被忽略。

rotation

number

动画结束时的视图旋转角度

anchor

ol.Coordinate

在动画过程中保持固定的点

duration

number

动画持续时间,单位为毫秒(ms),

默认为1000ms

easing

fucntion

动画控制函数,默认为ol.easing.inAndOut,该函数会返回一个介于0和1之间的数字,表示目标状态的进度。

3. 完整代码

其中libs文件夹下的包需要更换为自己下载的本地包或者引用在线资源。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>加载动画效果控件</title>
    <meta charset="utf-8" />
    <script src="../libs/js/ol-5.3.3.js"></script>
    <script src="../libs/js/jquery-2.1.1.min.js"></script>
    <link rel="stylesheet" href="../libs/css//ol.css">
    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 14px;
            font-family: '微软雅黑';
        }
        html,body{
            width:100%;
            height:100%;
        }
        #map {
            position: absolute;
            width: 100%;
            height: 100%;
        }
        .animate-div{
            position: relative;
            margin: 0 auto;
            padding: 20px;
            text-align: center;
        }
        .animate-btn{
            padding: 5px 10px;
            border-radius: 5px;
            font-size: 16px;
            color: #fff;
            background: #000000a1;
        }
    </style>
</head>
<body>
    <div id="map" title="地图显示"></div>
    <div class="animate-div">
        <button class="animate-btn" id="rotate-to">旋转定位到武汉</button>
        <button class="animate-btn" id="flex-to">弹性定位到北京</button>
        <button class="animate-btn" id="bounce-to">反弹定位到广州</button>
        <button class="animate-btn" id="rotate">围绕西安旋转</button>
        <button class="animate-btn" id="fly-to">飞行定位到杭州</button>
    </div>
</body>
</html>
<script>

    //==============================================================================//
    //============================天地图服务参数简单介绍============================//
    //================================vec:矢量图层=================================//
    //================================img:影像图层=================================//
    //================================cva:注记图层=================================//
    //=========================其中:_c表示经纬度,_w表示投影=======================//
    //==============================================================================//
    const TDTImgLayer = new ol.layer.Tile({
        title: "天地图影像图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=img_c&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const TDTVecLayer = new ol.layer.Tile({
        title: "天地图矢量图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const map = new ol.Map({
        target: "map",
        // 在加载瓦片图层时开启动画效果
        loadTilesWhileAnimate:true,
        loadTilesWhileInteracting: true,
        view: new ol.View({
            // center: [11444274, 12707441],
            center: [12992990, 13789010],
            // center: ol.proj.fromLonLat([102,25.5]),
            zoom: 15,
            worldsWrap: true,
            minZoom: 1,
            maxZoom: 20,
        }),
        controls: ol.control.defaults().extend([
            new ol.control.MousePosition()
        ])
    })
    map.addLayer(TDTVecLayer)
    map.addLayer(TDTImgLayer)
    
    // 定位点坐标
    const wuhan = ol.proj.fromLonLat([114.302387, 30.591255])
    const beijing = ol.proj.fromLonLat([116.400739, 39.913359])
    const guangzhou = ol.proj.fromLonLat([113.261081, 23.151553])
    const xian = ol.proj.fromLonLat([108.951639, 34.351322])
    const hangzhou = ol.proj.fromLonLat([120.205736, 30.253831])
    // 获取反弹值
    function bounce(t) {
        const s = 7.5625
        const p = 2.75
        let l = null
        if (t < l / 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) + 1
    }
    const view = map.getView()
    // 旋转定位
    document.getElementById('rotate-to').onclick = function () {
        const center = view.getCenter()
        view.animate({
            // 第一个过程
            // 动画结束时的视图中心,即当前视图中心与目标视图中心连线的中心点
            center: [
                center[0] + (wuhan[0] - center[0]) / 2,
                center[1] + (wuhan[1] - center[1]) / 2
            ],
            rotation: Math.PI,// 动画结束时的旋转角度,即180度
            easing:ol.easing.easeIn // 控制动画速度,开始缓慢之后逐渐加快
        }, {
            // 第二个过程
            center: wuhan,// 动画结束时的视图中心
            rotation: 2*Math.PI,// 动画结束时的旋转角度,即360度
            easing: ol.easing.easeIn // 控制动画速度,开始缓慢之后逐渐加快
        })
    }

    //弹性伸缩效果定位
    document.getElementById('flex-to').onclick = function () {
        view.animate({
            center: beijing,
            duration: 2000,//动画持续时间,单位为毫秒(ms)
            easing:elastic // 控自动画持续时间函数
        })
    }
    // 反弹效果定位
    document.getElementById('bounce-to').onclick = () => {
        view.animate({
            center: guangzhou,
            duration: 2000,
            easing:bounce // 控制动画持续时间函数
        })
    }
    // 自旋效果定位
    document.getElementById('rotate').onclick = ()=> {
        const rotation = view.getRotation()
        view.animate({
            // 第一个过程
            rotation: rotation + Math.PI, // 第一次动画旋转角度
            anchor: xian,// 自旋中心点
            easing: ol.easing.easeIn // 控自动画持续时间函数
        }, {
            // 第二个过程
            rotation: rotation + 2*Math.PI, // 第二次动画旋转角度
            anchor: xian,// 自旋中心点
            easing: ol.easing.easeOut// 控自动画持续时间函数
        })
    }
    // 飞行效果定位
    document.getElementById('fly-to').onclick = () => {
        const duration = 2000 //动画持续时间,单位为毫秒(ms)
        const zoom = view.getZoom()
        let parts = 2
        let called = false
        // 动画完成的回调函数
        function callback(complete) {
            --parts
            if (called) {
                return
            }
            if (parts === 0 || !complete) {
                called = true
            }
                 
        }
        // 第一个动画
        view.animate({
            center: hangzhou,
            duration: duration,
        }, callback)
        // 第二个动画
        view.animate({
            zoom: zoom -1 ,
            duration: duration/2,
        }, {
            zoom: zoom,
            duration:duration / 2
        },callback)
    }
</script>


如果你喜欢本文的话,可以点赞、收藏哦!也可以关注我的微信公众号,不定时更新有关WebGIS开发相关内容。

往期精彩推荐:



OpenLayers加载常用控件(八)

OpenLayers加载常用控件(八)


OpenLayers加载常用控件(八)



原文始发于微信公众号(GIS之路):OpenLayers加载常用控件(八)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/234681.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!