drag
本文回答:Marker 拖拽 —— draggable / dragstart / drag / dragend。
一、启用拖拽
const m = new vjmap.Marker({ draggable: true })
.setLngLat([lng, lat]);
m.addTo(map);
// 运行时
m.setDraggable(true);
m.isDraggable(); // true
二、拖拽事件
m.on("dragstart", () => {
console.log("开始拖拽");
});
m.on("drag", () => {
const ll = m.getLngLat();
console.log("拖拽中", ll.lng, ll.lat);
});
m.on("dragend", () => {
const ll = m.getLngLat();
console.log("拖拽结束", ll);
});
三、clickTolerance(点击 vs 拖拽的容差)
new vjmap.Marker({ draggable: true, clickTolerance: 3 })
鼠标在按下过程中移动超过 3 像素算拖拽,否则视为点击。
限制可发起拖拽的鼠标键(vjmap 引擎扩展,d.ts 未声明,TS 需 // @ts-ignore):默认任意键都能拖;disableDragButton 列出禁止的键,取值 left / middle / right / touch,多个用逗号连接:
const m2 = new vjmap.Marker({ draggable: true, disableDragButton: "middle,right" }) // 只允许左键和触摸拖动
.setLngLat([lng, lat]);
m2.addTo(map);
四、实时显示坐标(在 Marker 上)
const el = document.createElement("div");
el.style.cssText = "background:#fff;padding:4px;border:1px solid #aaa;cursor:move";
el.textContent = "拖我";
const m = new vjmap.Marker({ element: el, anchor: "bottom", draggable: true })
.setLngLat([lng, lat]);
m.addTo(map);
m.on("drag", () => {
const ll = m.getLngLat();
el.textContent = `(${ll.lng.toFixed(5)}, ${ll.lat.toFixed(5)})`;
});
五、拖到指定位置后吸附
m.on("dragend", () => {
const ll = m.getLngLat();
// 找最近的目标点
const snapTo = findNearest(ll, candidates);
if (distance(ll, snapTo) < 50) {
m.setLngLat(snapTo); // 吸附
}
});
六、拖出边界回弹
m.on("dragend", () => {
const ll = m.getLngLat();
const bounds = map.getMapExtent(); // CAD 全图范围(getGeoBounds() 默认只是全图×initViewScale/0.7)
// ⚠️ GeoBounds.contains 只收 GeoPoint:先把经纬度转回 CAD 点再判定
if (!bounds.contains(map.fromLngLat(ll))) {
m.setLngLat(savedLastValidLngLat);
alert("超出范围,已回弹");
} else {
savedLastValidLngLat = ll;
}
});
七、拖动时同步 popup 位置
const popup = new vjmap.Popup({ closeButton: false }).setText("拖我");
m.setPopup(popup);
m.togglePopup(); // 打开
m.on("drag", () => {
// popup 会自动跟着 marker 移动,不用手动调整
});
八、禁止拖拽
m.setDraggable(false);
九、坐标转 CAD
m.on("dragend", () => {
const ll = m.getLngLat();
const cadPt = map.fromLngLat(ll); // → { x, y }
console.log("CAD 坐标", cadPt.x, cadPt.y);
});
十、常见坑
- 拖拽过程中触发 click → 用
clickTolerance容差(默认 0 即继承 map)。 - 拖拽后位置不对 → 可能 anchor 是 center 但视觉上以为是 bottom;拖的是几何中心。
- CSS 禁用 user-select:
cursor: move; user-select: none;,避免拖拽时选中文本。 - setDraggable(true) 后没拖 → 检查自定义 element 上有没有阻止 pointer 事件的 CSS。
- 多个 Marker 同时拖:vjmap Marker 是独立 DOM,可以独立拖;但 hitTest 顺序取决于 z-index。