官网demo地址:
Custom Interactions
这个示例介绍了如何在地图上自定义一个交互实现在地图上拖拽、移动要素。
首先是加载了三个要素到地图上,一个点、一个多边形、一条线。
const pointFeature = new Feature(new Point([0, 0])); const lineFeature = new Feature( new LineString([ [-1e7, 1e6], [-1e6, 3e6], ]) ); const polygonFeature = new Feature( new Polygon([ [ [-3e6, -1e6], [-3e6, 1e6], [-1e6, 1e6], [-1e6, -1e6], [-3e6, -1e6], ], ]) ); new VectorLayer({ source: new VectorSource({ features: [pointFeature, lineFeature, polygonFeature], }), style: { "icon-src": "data/icon.png", "icon-opacity": 0.95, "icon-anchor": [0.5, 46], //设置图标锚点的位置 "icon-anchor-x-units": "fraction", //指定锚点的水平单位是比例值 "icon-anchor-y-units": "pixels", //指定锚点的垂直单位是像素值 "stroke-width": 3, "stroke-color": [255, 0, 0, 1], "fill-color": [0, 0, 255, 0.6], }, }),
然后创建了一个类继承原本的PointerInteraction,将四个事件作为参数传递给PointerInteraction。来处理事件逻辑。
class Drag extends PointerInteraction { constructor() { super({ handleDownEvent: handleDownEvent, //按下事件 handleDragEvent: handleDragEvent, //拖动事件 handleMoveEvent: handleMoveEvent, //移动事件 handleUpEvent: handleUpEvent, //释放事件 }); //存储鼠标点击时的坐标 this.coordinate_ = null; //用于存储鼠标悬停在要素上时的光标样式 this.cursor_ = "pointer"; //存储被拖拽的要素 this.feature_ = null; //存储之前的光标样式,以便恢复 this.previousCursor_ = undefined; } }
可以看下源码中PointerInteraction的定义。
这里移动要素用了一个geometry.translate()方法,如果我们自己写方法来完成移动的话会比较麻烦。
/** * @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event. */ function handleDragEvent(evt) { //计算鼠标拖动的位移 const deltaX = evt.coordinate[0] - this.coordinate_[0]; const deltaY = evt.coordinate[1] - this.coordinate_[1]; //平移被拖拽要素的几何图形 const geometry = this.feature_.getGeometry(); geometry.translate(deltaX, deltaY); //更新存储的坐标为当前鼠标的位置 this.coordinate_[0] = evt.coordinate[0]; this.coordinate_[1] = evt.coordinate[1]; }
重新定义了一个Drag类,我放在了utils下的Drag.js中便于多次使用。
import Drag from '@/utils/Drag' const map = new Map({ interactions: defaultInteractions().extend([new Drag()]), })
完整代码:
utils/Drag.js:
import { Pointer as PointerInteraction, } from "ol/interaction.js"; class Drag extends PointerInteraction { constructor() { super({ handleDownEvent: handleDownEvent, //按下事件 handleDragEvent: handleDragEvent, //拖动事件 handleMoveEvent: handleMoveEvent, //移动事件 handleUpEvent: handleUpEvent, //释放事件 }); //存储鼠标点击时的坐标 this.coordinate_ = null; //用于存储鼠标悬停在要素上时的光标样式 this.cursor_ = "pointer"; //存储被拖拽的要素 this.feature_ = null; //存储之前的光标样式,以便恢复 this.previousCursor_ = undefined; } } /** * @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event. * @return {boolean} `true` to start the drag sequence. */ function handleDownEvent(evt) { const map = evt.map; // 在地图上检测鼠标点击的位置是否有要素,如果有,则存储要素和点击位置的坐标 const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { return feature; }); if (feature) { this.coordinate_ = evt.coordinate; this.feature_ = feature; } return !!feature; } /** * @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event. */ function handleDragEvent(evt) { //计算鼠标拖动的位移 const deltaX = evt.coordinate[0] - this.coordinate_[0]; const deltaY = evt.coordinate[1] - this.coordinate_[1]; //平移被拖拽要素的几何图形 const geometry = this.feature_.getGeometry(); geometry.translate(deltaX, deltaY); //更新存储的坐标为当前鼠标的位置 this.coordinate_[0] = evt.coordinate[0]; this.coordinate_[1] = evt.coordinate[1]; } /** * @param {import("../src/ol/MapBrowserEvent.js").default} evt Event. */ function handleMoveEvent(evt) { if (this.cursor_) { const map = evt.map; const feature = map.forEachFeatureAtPixel( evt.pixel, function (feature) { return feature; } ); //检测鼠标移动到的要素,如果有要素则改变光标样式。 const element = evt.map.getTargetElement(); if (feature) { if (element.style.cursor != this.cursor_) { this.previousCursor_ = element.style.cursor; element.style.cursor = this.cursor_; } //如果鼠标移出要素,则恢复之前的光标样式 } else if (this.previousCursor_ !== undefined) { element.style.cursor = this.previousCursor_; this.previousCursor_ = undefined; } } } /** * @return {boolean} `false` to stop the drag sequence. */ //重置存储的坐标和要素,表示拖拽序列结束 function handleUpEvent() { this.coordinate_ = null; this.feature_ = null; return false; } export default Drag
.vue文件:
自定义工具
还没有评论,来说两句吧...