百度地图API详解之地图容器

地图容器就是包含地图区域的那个框框,这个有什么可说的呢?请您往下看。

通常我们会给地图容器一个固定的尺寸:

  
  
<div id="map" style="width:500px;height:320px"></div>

假设上面的div元素就是我们的地图容器,那么地图显示范围就是500x320:

有时我们希望地图容器随着浏览器变化而变化,那么我们将样式调整为:

  
  
html{height:100%} body{height:100%;margin:0px;padding:0px} #map{height:100%}

这时地图区域会跟随着浏览器的大小自动变化,另外API也会根据外框尺寸的变化自动铺设图块以保证视野内地图是完整的。通过监听map的resize事件可得知地图容器在什么时候发生变化了。注意在容器大小发生变化时,API默认保证地图到左边和上边的距离始终一致,这样做的目的也是保证地图相对于人眼的位置不发生变化(因为用户在修改浏览器窗口尺寸时通常都会调整右下方的点),简单说就是用户不会感到地图有任何的“跳动”:

我们看到随着浏览器窗口变大,地图逐渐展示出北京市东南区域的图块,而整个地图相对于左上角的位置没有发生变化。还有一点需要注意,这种情况下地图中心点是发生变化的了,之前中心位于天安门附近,之后中心点向东南方向移动了。我们可以通过监听resize事件来验证:

  
  
map.addEventListener('resize', function(){ console.log(this.getCenter().lng + ',' + this.getCenter().lat); });

下面是在firebug中看到的数据,可以看出经度不断变大,纬度不断减小,说明中心点向东南方向移动了。

如果希望不管容器怎样变化地图中心点都保持一致该怎么办呢?首先你需要禁止地图自动适应容器变化,这可通过设置MapOptions的enableAutoResize属性为false或者调用Map的disableAutoResize方法来实现:

  
  
var map = new Map('map', {enableAutoResize: false});

此时你会发现容器变化时,地图不再自动铺图,也不会派发resize事件了。此时我们需要自己监听body的resize事件:

  
  
<body onresize="resizeMap()">

resizeMap方法中需要做如下工作:

  
  
function resizeMap() { var center = map.getCenter(); map.checkResize(); map.setCenter(center); }
我们先获取地图中心点,然后调用Map的checkResize方法通知地图容器发生变化,此时地图会进行铺图,最后我们设置地图中心点为之前的获取的值。这样不论地图容器如何变化,地图中心点始终保持一致。去哪(qunar.com)酒店的页面上就有这样一个地图,其提供了大图模式和小图模式切换的按钮,切换后地图中心点保持一致(地址在此)。

还有一种稍复杂的情况,对于以地图应用为主的网站,通常界面布局会是如下样式:

网站上方是搜索区域,左侧是结果展示区域,剩下的区域用来展示地图。网站很可能提供一个全屏按钮来隐藏上面和左面的区域,为了获得更好的用户体验,我们希望此时地图相对于整个浏览器的位置不会发生变化,仿佛上面和左面的区域是盖在地图上的。这样空说可能不好理解,我们来看实际的例子:

首先准备完整的HTML页面:

复制代码
  
  
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>百度地图API详解</title> <style type="text/css"> html{height:100%;} body{height:100%;margin:0px;padding:0px;} #top{width:100%;height:79px;border-bottom:1px solid #ccc;background:#eee;} #aside{position:absolute;top:80px;width:159px;border-right:1px solid #bbb;background:#ddd;} #map{margin-left:160px;} </style> <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script> </head> <body onload="init()" onresize="checkSize()"> <div id="top"></div> <div id="main"> <div id="aside"></div> <div id="map"></div> </div> </body> <script type="text/javascript"> function checkSize() { var h = document.documentElement.clientHeight; document.getElementById('aside').style.height = h - 80 + "px"; document.getElementById('map').style.height = h - 80 + "px"; } function init() { checkSize(); var map = new BMap.Map('map'); map.centerAndZoom('北京'); window.map = map; } </script> </html>
复制代码

页面效果如下:

这时我们修改浏览器窗口大小,地图会自动铺图并且地图相对于左边和上边的距离保持不变,一切效果OK。下面我们添加编写一个全屏函数:

复制代码
  
  
function toFullScreen() { document.getElementById('top').style.display = 'none'; document.getElementById('aside').style.display = 'none'; var h = document.documentElement.clientHeight; var mapContainer = document.getElementById('map'); mapContainer.style.height = h + "px"; mapContainer.style.marginLeft = "0"; }
复制代码

这个函数将两个区域进行隐藏,同时调整地图容器,我们在控制台调用这个方法,会得到这个结果:

和之前的图对比可以发现地图区域向左上方移动了,这样会给用户地图“跳动”的感觉,为了让地图与用户眼睛的位置保持一致,我们需要修改toFullScreen函数:

复制代码
  
  
function toFullScreen() { map.disableAutoResize(); var h = document.documentElement.clientHeight; var curPix = map.pointToPixel(map.getCenter()); var newPix = new BMap.Pixel(curPix.x - 80, curPix.y - 40); var newCenter = map.pixelToPoint(newPix); document.getElementById('top').style.display = 'none'; document.getElementById('aside').style.display = 'none'; var mapContainer = document.getElementById('map'); mapContainer.style.height = h + "px"; mapContainer.style.marginLeft = "0"; map.checkResize(); map.setCenter(newCenter); map.enableAutoResize(); }
复制代码

这里大致的思路是,首先停止地图自动适应容器变化,接着通过坐标转换得到当前中心点对应的像素坐标curPix,再计算出全屏后中心点的像素坐标newPix,进而转换为经纬度newCenter。下面调用修改容器尺寸并调用checkResize通知地图容器发生变化,接着再重新设置中心点并恢复自动适应容器变化。效果如下:

此时,全屏过程中地图没有任何的“跳动”,从而提供了较好的用户体验。谷歌地图也使用了类似的效果,当左侧面板收起时,地图区域自动向左侧扩展,而没有向左侧跳动。

最后说明一下,上面的checkResize方法没有考虑全屏幕的情况,因为它不是本文的重点,就不再这里给出具体代码了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值