n-ol-pointermove
组件介绍
依赖
使用示例
点我查看代码
vue
<script setup lang="ts">
import type { NOlPointermoveOption, NOlPointermoveParams, OlMapInst } from '@summeruse/ol'
import { createVectorLayer, getOSMLayer, NOlPointermove, OlMap } from '@summeruse/ol'
import Feature from 'ol/Feature'
import { Point, Polygon } from 'ol/geom'
import { computed, h, onMounted, ref } from 'vue'
const olMapRef = ref<OlMapInst>()
const olMap = computed(() => {
return olMapRef.value?.olMap
})
const { source, layer } = createVectorLayer()
const feature = new Feature({
geometry: new Point([0, 0]),
type: 'point',
data: {
name: '点',
},
})
source.addFeature(feature)
const feature2 = new Feature({
geometry: new Polygon([
[
[1000000, 1000000],
[1000000, 5000000],
[5000000, 5000000],
[5000000, 1000000],
],
]),
type: 'polygon',
data: {
name: '多边形',
},
})
source.addFeature(feature2)
onMounted(() => {
olMap.value?.addLayer(getOSMLayer())
olMap.value?.addLayer(layer)
})
function createOptions(data: NOlPointermoveParams): NOlPointermoveOption {
if (data.features.length) {
const feature = data.features[0]
const type = feature.get('type')
if (type === 'point') {
return {
showArrow: true,
content: feature.get('data').name,
}
}
else if (type === 'polygon') {
return {
showArrow: false,
raw: true,
followTarget: 'feature',
content: h('div', {
class: 'flex flex-col gap-2 bg-#bafc p-2 rounded-md',
}, {
default: () => [
h('div', {
class: 'flex items-center gap-2',
}, {
default: () => [
h('div', {
class: 'w-4 h-4 bg-#000',
}),
h('div', {
class: 'text-#000',
}, {
default: () => feature.get('data').name,
}),
],
}),
],
}),
}
}
}
}
</script>
<template>
<OlMap ref="olMapRef" class="w-100% h-400px">
<template #default="{ olMap: map }">
<NOlPointermove v-if="map" :ol-map="map" :create-options />
</template>
</OlMap>
</template>
组件代码
点我查看代码
vue
<script setup lang="ts">
import type { PopoverPlacement } from 'naive-ui'
import type { VNodeChild } from 'vue'
import type { NOlPointermoveProps } from './props'
import { RenderVNode } from '@summeruse/common'
import { NPopover } from 'naive-ui'
import { getCenter } from 'ol/extent'
import { onMounted, ref, shallowRef } from 'vue'
const props = defineProps<NOlPointermoveProps>()
const popoverConfig = ref({
visible: false,
x: 0,
y: 0,
})
const child = shallowRef<(() => VNodeChild) | VNodeChild | string>()
const placement = ref<PopoverPlacement>('bottom-start')
const raw = ref(false)
const showArrow = ref(false)
onMounted(() => {
props.olMap?.on('pointermove', (event) => {
const features = props.olMap.getFeaturesAtPixel(event.pixel)
popoverConfig.value.visible = false
const options = props.createOptions({
pixel: event.pixel,
coordinate: event.coordinate,
features,
})
if (options) {
child.value = options.content
placement.value = options.placement || 'bottom-start'
showArrow.value = options.showArrow || false
raw.value = options.raw || false
popoverConfig.value.visible = true
if ((options.followTarget === 'feature') && (features.length > 0)) {
const feature = features[0]
const geometry = feature.getGeometry()
if (geometry) {
const extent = geometry.getExtent()
const center = getCenter(extent)
const pixel = props.olMap.getPixelFromCoordinate(center)
const { top, left } = props.olMap.getViewport().getBoundingClientRect()
popoverConfig.value.x = pixel[0] + left
popoverConfig.value.y = pixel[1] + top
return
}
}
// console.log(event)
const { clientX, clientY } = event.originalEvent as PointerEvent
popoverConfig.value.x = clientX
popoverConfig.value.y = clientY
}
})
})
</script>
<template>
<NPopover
:show-arrow :raw :placement :show="popoverConfig.visible" :x="popoverConfig.x" :y="popoverConfig.y"
trigger="manual" class="n-ol-pointermove" :theme-overrides="{
boxShadow: 'none',
}"
>
<RenderVNode :dynamic-v-node="child" />
</NPopover>
</template>
Props
点我查看代码
ts
import type { PopoverPlacement } from 'naive-ui'
import type { Map as OLMap } from 'ol'
import type { Coordinate } from 'ol/coordinate'
import type { FeatureLike } from 'ol/Feature'
import type { Pixel } from 'ol/pixel'
import type { VNodeChild } from 'vue'
export interface NOlPointermoveParams {
pixel: Pixel
coordinate: Coordinate
features: FeatureLike[]
}
export type NOlPointermoveOption = {
content: (() => VNodeChild) | VNodeChild | string
raw?: boolean
showArrow?: boolean
placement?: PopoverPlacement
// 跟随鼠标 | 跟随要素
followTarget?: 'mouse' | 'feature'
} | undefined
export interface NOlPointermoveProps {
olMap: OLMap
createOptions: (data: NOlPointermoveParams) => NOlPointermoveOption
}