交互与事件
SDK 提供了丰富的地图交互功能和事件系统,支持鼠标、触摸、键盘等多种交互方式。
鼠标交互
点击事件
javascript
// 监听地图点击
sdk.on("click", (e) => {
console.log("点击位置:", e.lngLat);
console.log("点击的要素:", e.features);
// 查询点击位置的要素
const features = sdk.queryRenderedFeatures(e.point);
console.log("查询到的要素:", features);
});
// 监听特定图层点击
sdk.on("click", "airport", (e) => {
console.log("点击了机场图层:", e.features[0]);
});双击事件
javascript
sdk.on("dblclick", (e) => {
// 双击放大
sdk.zoomIn();
});右键菜单
javascript
sdk.on("contextmenu", (e) => {
e.preventDefault();
// 显示自定义右键菜单
showContextMenu(e.lngLat);
});鼠标悬停
javascript
// 鼠标进入
sdk.on("mouseenter", "airport", (e) => {
// 改变鼠标样式
sdk.getCanvas().style.cursor = "pointer";
});
// 鼠标离开
sdk.on("mouseleave", "airport", (e) => {
sdk.getCanvas().style.cursor = "";
});鼠标移动
javascript
sdk.on("mousemove", (e) => {
// 实时显示鼠标位置
updateMousePosition(e.lngLat);
});拖拽交互
启用/禁用拖拽
javascript
// 禁用拖拽
sdk.dragPan.disable();
// 启用拖拽
sdk.dragPan.enable();拖拽事件
javascript
sdk.on("dragstart", () => {
console.log("开始拖拽");
});
sdk.on("drag", () => {
console.log("拖拽中");
});
sdk.on("dragend", () => {
console.log("拖拽结束");
});缩放交互
鼠标滚轮缩放
javascript
// 禁用滚轮缩放
sdk.scrollZoom.disable();
// 启用滚轮缩放
sdk.scrollZoom.enable();
// 监听缩放事件
sdk.on("zoom", () => {
console.log("缩放级别:", sdk.getZoom());
});
sdk.on("zoomstart", () => {
console.log("开始缩放");
});
sdk.on("zoomend", () => {
console.log("缩放结束");
});双击缩放
javascript
// 禁用双击缩放
sdk.doubleClickZoom.disable();
// 启用双击缩放
sdk.doubleClickZoom.enable();旋转交互
启用/禁用旋转
javascript
// 禁用旋转(右键拖拽)
sdk.dragRotate.disable();
// 启用旋转
sdk.dragRotate.enable();旋转事件
javascript
sdk.on("rotate", () => {
console.log("旋转角度:", sdk.getBearing());
});
sdk.on("rotatestart", () => {
console.log("开始旋转");
});
sdk.on("rotateend", () => {
console.log("旋转结束");
});键盘交互
启用/禁用键盘
javascript
// 禁用键盘控制
sdk.keyboard.disable();
// 启用键盘控制
sdk.keyboard.enable();键盘事件
SDK 默认支持以下键盘快捷键:
+/-:缩放←/→/↑/↓:平移Shift + ←/Shift + →:旋转
javascript
// 监听键盘事件
document.addEventListener("keydown", (e) => {
if (e.key === "+" || e.key === "=") {
sdk.zoomIn();
} else if (e.key === "-") {
sdk.zoomOut();
}
});触摸交互(移动端)
触摸事件
javascript
sdk.on("touchstart", (e) => {
console.log("触摸开始");
});
sdk.on("touchmove", (e) => {
console.log("触摸移动");
});
sdk.on("touchend", (e) => {
console.log("触摸结束");
});捏合缩放
javascript
sdk.on("touchzoom", () => {
console.log("捏合缩放");
});要素查询
查询渲染的要素
javascript
// 查询点击位置的要素
sdk.on("click", (e) => {
const features = sdk.queryRenderedFeatures(e.point);
console.log("查询到的要素:", features);
});
// 查询指定图层的要素
const features = sdk.queryRenderedFeatures(e.point, {
layers: ["airport", "airline"],
});
// 查询指定区域的要素
const boxFeatures = sdk.queryRenderedFeatures([
[x1, y1],
[x2, y2],
]);查询源数据
javascript
// 查询源中的所有要素
const sourceFeatures = sdk.querySourceFeatures("airport-source", {
sourceLayer: "airport",
filter: ["==", "type", "civil"],
});事件管理
添加事件监听
javascript
// 添加事件监听
const handler = (e) => {
console.log("事件触发:", e);
};
sdk.on("click", handler);移除事件监听
javascript
// 移除特定监听器
sdk.off("click", handler);
// 移除所有监听器
sdk.off("click");一次性事件监听
javascript
// 只监听一次
sdk.once("loadComplete", () => {
console.log("地图加载完成(只执行一次)");
});自定义交互
使用 ClickManager
javascript
// 点击时显示弹窗
sdk.clickObj.clickPopup(
"airport",
(feature) => {
return `<h3>${feature.properties.name}</h3>`;
},
{
anchor: "bottom",
closeButton: true,
}
);使用 HoverManager
javascript
// 悬停时显示信息
sdk.hover.hoverPopup(
"airport",
(feature) => {
return `<div>${feature.properties.name}</div>`;
},
{
anchor: "top",
}
);使用 SelectFeature
javascript
// 启用要素选择
sdk.selector.enable({
onSelect: (feature, properties) => {
console.log("选中的要素:", feature);
},
isHighlight: true, // 高亮选中要素
isMultiSelect: false, // 是否支持多选
});
// 禁用要素选择
sdk.selector.disable();
// 清除选择
sdk.selector.clearSelection();完整示例
javascript
let sdk;
async function initMap() {
sdk = new navMap.MapSDK({
container: "map",
center: [116.39, 39.9],
zoom: 10,
});
sdk.on("loadComplete", () => {
setupInteractions();
});
}
function setupInteractions() {
// 1. 点击查询要素
sdk.on("click", (e) => {
const features = sdk.queryRenderedFeatures(e.point, {
layers: ["airport"],
});
if (features.length > 0) {
const feature = features[0];
showFeatureInfo(feature);
}
});
// 2. 悬停高亮
sdk.on("mouseenter", "airport", (e) => {
sdk.getCanvas().style.cursor = "pointer";
highlightFeature(e.features[0]);
});
sdk.on("mouseleave", "airport", () => {
sdk.getCanvas().style.cursor = "";
clearHighlight();
});
// 3. 双击缩放
sdk.on("dblclick", (e) => {
sdk.flyTo({
center: e.lngLat,
zoom: sdk.getZoom() + 1,
duration: 500,
});
});
// 4. 右键菜单
sdk.on("contextmenu", (e) => {
e.preventDefault();
showContextMenu(e.lngLat);
});
// 5. 缩放时调整图层
sdk.on("zoom", () => {
const zoom = sdk.getZoom();
if (zoom > 12) {
sdk.showLayers(["detail-layer"]);
} else {
sdk.hideLayers(["detail-layer"]);
}
});
// 6. 使用选择管理器
sdk.selector.enable({
onSelect: (feature) => {
console.log("选中要素:", feature);
},
isHighlight: true,
});
}
function showFeatureInfo(feature) {
const popup = new navMap.Popup()
.setLngLat(feature.geometry.coordinates)
.setHTML(`<h3>${feature.properties.name}</h3>`)
.addTo(sdk.map);
}
initMap();注意事项
- 事件顺序:确保在地图
loadComplete后再添加事件监听 - 性能优化:避免在频繁触发的事件(如
mousemove)中执行复杂操作 - 事件清理:页面卸载前记得移除事件监听,避免内存泄漏
- 移动端适配:移动端优先使用触摸事件,而非鼠标事件
