注:当前使用的是 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开发相关内容。
往期精彩推荐:
原文始发于微信公众号(GIS之路):OpenLayers加载常用控件(八)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/234681.html