3、地图控制:移动地图、缩放地图、获取当前视野范围、地图事件监听
地图控制,说白了就是让地图听你的话。你想让它往哪看,它就往哪看;你想让它放大看细节,它就放大。这一节,我带你把这几个核心操作彻底搞明白。
3.1 移动地图:让地图“走”起来
移动地图,其实就是改变地图的中心点坐标。小程序里,我们用的是 moveToLocation 和 translateMap 这两个方法。
moveToLocation 最简单,直接定位到当前用户的经纬度。我早期做外卖项目时,用户一进来就调用这个,地图“嗖”一下定位到用户位置,体验很好。
// 移动到用户当前位置
this.mapCtx.moveToLocation({
latitude: 39.92,
longitude: 116.46,
success: () => {
console.log('移动成功');
}
});
translateMap 则更灵活,可以指定一个偏移量。比如你想让地图往东平移100像素,就这么写:
this.mapCtx.translateMap({
x: 100, // 水平偏移,单位像素
y: 0, // 垂直偏移
success: () => {
console.log('平移完成');
}
});
onReady 生命周期里操作。
3.2 缩放地图:看得更远或更细
缩放地图,控制的是 scale 属性。范围是 3 到 20,数字越大,看得越细。
举个例子:3 级能看到整个中国,20 级能看到你家楼下的便利店。我个人做景区导览时,常用 15-18 级,这个范围既能看清路,又不会太碎。
// 设置缩放级别
this.mapCtx.setScale({
scale: 15,
duration: 300, // 动画时长,单位毫秒
success: () => {
console.log('缩放成功');
}
});
还有一种方式,直接调用 zoomIn 和 zoomOut:
// 放大一级
this.mapCtx.zoomIn();
// 缩小一级
this.mapCtx.zoomOut();
3.3 获取当前视野范围
有时候,你需要知道用户当前看到了地图的哪一块。比如,用户拖动地图后,你想重新加载这个区域内的标记点。
用 getRegion 方法就能拿到:
this.mapCtx.getRegion({
success: (res) => {
const { southwest, northeast } = res;
console.log('西南角:', southwest.latitude, southwest.longitude);
console.log('东北角:', northeast.latitude, northeast.longitude);
}
});
返回的是西南角和东北角的经纬度,说白了就是一个矩形范围。我经常拿这个来做“视野内数据加载”——用户拖到哪,就加载哪里的数据,省流量又高效。
另外,getScale 可以拿到当前的缩放级别:
this.mapCtx.getScale({
success: (res) => {
console.log('当前缩放级别:', res.scale);
}
});
3.4 地图事件监听:让地图“说话”
地图不能光会动,还得会“说话”。用户点击、拖动、缩放,地图都应该能告诉我们。
点击事件(bindtap)
用户点地图上的某个位置,我们拿到经纬度,然后可以做点事,比如添加标记:
<map
id="myMap"
bindtap="onMapTap"
/>
onMapTap(e) {
const { latitude, longitude } = e.detail;
console.log('点击位置:', latitude, longitude);
// 在这里添加标记点
}
移动事件(bindregionchange)
用户拖动地图时触发。注意,这个事件会触发两次:开始拖动和结束拖动。我一般只关心结束那次:
<map
id="myMap"
bindregionchange="onRegionChange"
/>
onRegionChange(e) {
if (e.type === 'end') {
console.log('拖动结束,视野变了');
// 重新加载数据
}
}
缩放事件(bindscalechange)
用户双指缩放时触发。同样有开始和结束两个阶段:
onScaleChange(e) {
const { scale } = e.detail;
console.log('当前缩放级别:', scale);
// 根据缩放级别调整标记点的大小
}
bindregionchange 里直接调接口加载数据,结果用户快速拖动时,接口被调了几十次,页面直接卡死。后来我加了防抖处理,只取最后一次结果,问题就解决了。
3.5 综合示例:一个可交互的地图
把上面这些串起来,就是一个完整的地图控制组件。我贴一个我项目里用过的简化版:
Page({
data: {
latitude: 39.92,
longitude: 116.46,
scale: 15,
markers: []
},
onReady() {
this.mapCtx = wx.createMapContext('myMap');
},
// 移动到我当前的位置
goToMyLocation() {
this.mapCtx.moveToLocation();
},
// 放大
zoomIn() {
this.mapCtx.zoomIn();
},
// 缩小
zoomOut() {
this.mapCtx.zoomOut();
},
// 点击地图添加标记
onMapTap(e) {
const { latitude, longitude } = e.detail;
this.setData({
markers: [{
id: Date.now(),
latitude,
longitude,
title: '新标记'
}]
});
},
// 视野变化后更新数据
onRegionChange(e) {
if (e.type === 'end') {
this.mapCtx.getRegion({
success: (res) => {
console.log('新视野范围:', res);
// 这里可以加载新区域的数据
}
});
}
}
});
嗯,到这里,地图控制的核心操作就全了。你想想看,移动、缩放、获取视野、监听事件,这几个能力组合起来,基本能覆盖 90% 的地图交互场景。下一节,我们聊聊怎么在地图上画路线和覆盖物,那才是真正好玩的地方。