# 可拖拽弹窗
🥡
有时间在整理
<template>
<div id="mapcontainer" class="mapcontainer"></div>
<div id="popup" ref="popupRef">
<div class="popupStyle">该弹窗可拖拽</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { Map, View, Overlay, Feature } from "ol"; // 地图实例方法、视图方法
import { Style, Stroke, Icon } from "ol/style";
import { LineString, Point } from "ol/geom";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import DragPan from 'ol/interaction/DragPan'; // 拖拽交互
import marker from '@/assets/markers/marker.png'
import {
overlay,
mousePosition
} from './mapconfig.js'
import "ol/ol.css"; // 地图样式
const map = ref(null); // 存放地图实例
const popupRef = ref(null) // 弹窗ref
const popupOverlay = ref(null) // 弹窗实例
// 添加marker Point
let iconFeature = null;
let lineFeature = null;
const addPointMarker = (coordinate = [104.03228, 30.72147]) => {
// marker
iconFeature = new Feature({
geometry: new Point(coordinate),
featureType: 'marker'
});
const iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: marker,
scale: 0.3
})
});
iconFeature.setStyle(iconStyle);
// line
lineFeature = new Feature({
geometry: new LineString([])
});
var lineStyle = new Style({
stroke: new Stroke({
color: '#ffcc33',
width: 3,
lineDash: [10, 10]
})
});
var vectorSource = new VectorSource({
features: [iconFeature, lineFeature] // 组合要素 也可以使用addFeature方法
});
var vectorLayer = new VectorLayer({
source: vectorSource,
style: [lineStyle],
updateWhileInteracting: true, // 自动更新位置
});
map.value.addLayer(vectorLayer);
}
const addPopup = (coordinate = [104.03228, 30.72147]) => {
popupOverlay.value = new Overlay({
element: popupRef.value,
positioning: 'bottom-center',
stopEvent: false,
dragging: false,
offset: [90, -90]
});
popupOverlay.value.setPosition(coordinate);
map.value.addOverlay(popupOverlay.value);
}
var dragPan;
const inintMap = () => {
map.value = new Map({
target: "mapcontainer", // 对应页面里 id 为 map 的元素
layers: [overlay],
view: new View({
projection: "EPSG:4326",
center: [104.03228760, 30.72147313], // 地图中心点
minZoom: 12, // 地图缩放最小级别
maxZoom: 18, // 地图缩放最大级别
zoom: 14, // 地图缩放级别(打开页面时默认级别)
}),
overlays: [],
controls: [mousePosition]
})
map.value.getInteractions().forEach(function (interaction) {
if (interaction instanceof DragPan) {
dragPan = interaction;
}
});
popupRef.value.addEventListener('mousedown', function (evt) {
dragPan.setActive(false);
popupOverlay.value.set('dragging', true);
console.info('start dragging');
});
map.value.on('pointermove', function (evt) {
var startPoint = iconFeature.getGeometry().getCoordinates();
if (popupOverlay.value && popupOverlay.value.get('dragging')) {
var dd2 = map.value.getPixelFromCoordinate(evt.coordinate);
var newX = dd2[0] - 90; // 减去偏移量
var newY = dd2[1] - (-90);
var newPoint = map.value.getCoordinateFromPixel([newX, newY]);
popupOverlay.value.setPosition(newPoint);
lineFeature.getGeometry().setCoordinates([startPoint, evt.coordinate]);
}
});
map.value.on('pointerup', function (evt) {
if (popupOverlay.value && popupOverlay.value.get('dragging') === true) {
console.info('stop dragging');
dragPan.setActive(true);
popupOverlay.value.set('dragging', false);
}
});
mapClick()
}
// 地图点击事件
const mapClick = () => {
map.value.on("singleclick", (evt) => {
const feature = map.value.forEachFeatureAtPixel(
evt.pixel,
function (feature) {
return feature;
}
);
// 点击图标才出现信息框
if (feature && feature.values_.featureType === "marker") {
let featureCoordinate = iconFeature.getGeometry().getCoordinates();
addPopup(featureCoordinate) // 添加信息框
var dd2 = map.value.getPixelFromCoordinate(featureCoordinate);
var newX = dd2[0] + 90; // 加上偏移量
var newY = dd2[1] - 90;
let endLineCoordinate = map.value.getCoordinateFromPixel([newX, newY]);
lineFeature.getGeometry().setCoordinates([featureCoordinate, endLineCoordinate]);
} else {
popupOverlay.value.setPosition(null);
lineFeature.getGeometry().setCoordinates([]);
}
});
};
onMounted(() => {
inintMap()
addPointMarker() // 添加点标记
})
</script>
<style lang="scss" scoped>
#mapcontainer {
position: relative;
width: 100%;
height: 100vh
}
#popup {
cursor: pointer;
}
.popupStyle {
position: relative;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: white;
background-color: rgba(0, 0, 0, 0.4);
}
</style>
← 地图画路径