Skip to content

Commit ab675b2

Browse files
committed
feat(ol-interaction-pointer): add new pointer interaction
which wraps: https://openlayers.org/en/latest/apidoc/module-ol_interaction_Pointer-PointerInteraction.html closes #339
1 parent 45021d2 commit ab675b2

File tree

6 files changed

+212
-0
lines changed

6 files changed

+212
-0
lines changed

Diff for: docs/.vitepress/config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ export const config: UserConfig = {
384384
text: "ol-interaction-modify",
385385
link: "/componentsguide/interactions/modify/",
386386
},
387+
{
388+
text: "ol-interaction-pointer",
389+
link: "/componentsguide/interactions/pointer/",
390+
},
387391
{
388392
text: "ol-interaction-select",
389393
link: "/componentsguide/interactions/select/",

Diff for: docs/componentsguide/interactions/pointer/index.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# ol-interaction-pointer
2+
3+
Component that handles user-defined functions on `down`, `move`, `up` and `drag` events.
4+
5+
[[toc]]
6+
7+
## Demo
8+
9+
<script setup>
10+
import PointerDemo from "@demos/PointerDemo.vue"
11+
</script>
12+
13+
<ClientOnly>
14+
<PointerDemo/>
15+
</ClientOnly>
16+
17+
## Setup
18+
19+
<!--@include: ../../interactions.plugin.md-->
20+
21+
## Usage
22+
23+
| Plugin Usage | Explicit Import |
24+
|----------------------------|:-------------------------------------:|
25+
| `<ol-interaction-pointer>` | `<Interactions.OlInteractionPointer>` |
26+
27+
::: code-group
28+
29+
<<< ../../../../src/demos/PointerDemo.vue
30+
31+
:::
32+
33+
## Properties
34+
35+
### stopDown
36+
37+
Should the down event be propagated to other interactions, or should be stopped?
38+
39+
- **Type**: `((arg0: boolean) => boolean) | undefined`
40+
41+
## Events
42+
43+
You have access to all Events from the underlying interaction.
44+
Check out [the official OpenLayers docs](https://openlayers.org/en/latest/apidoc/module-ol_interaction_Pointer-PointerInteraction.html) to see the available events tht will be fired.
45+
46+
In addition, the events `down`, `move`, `up`, `drag` and `event`, are fired.
47+
48+
```html
49+
<ol-interaction-pointer
50+
@down="handleDownEvent"
51+
@move="handleMoveEvent"
52+
@up="handleUpEvent"
53+
@drag="handleDragEvent"
54+
@error="handleErrorEvent"
55+
/>
56+
```
57+
58+
## Methods
59+
60+
You have access to all Methods from the underlying interaction.
61+
Check out [the official OpenLayers docs](https://openlayers.org/en/latest/apidoc/module-ol_interaction_Pointer-PointerInteraction.html) to see the available methods.
62+
63+
To access the source, you can use a `ref()` as shown below:
64+
65+
```vue
66+
<template>
67+
<!-- ... -->
68+
<ol-interaction-pointer ref="pointerRef" @down="handleDownEvent" />
69+
<!-- ... -->
70+
</template>
71+
72+
<script setup lang="ts">
73+
import { ref, onMounted } from "vue";
74+
import type Pointer from "ol/interaction/Pointer";
75+
76+
const pointerRef = ref<{ pointer: Pointer } | null>(null);
77+
78+
onMounted(() => {
79+
const pointer: Pointer = pointerRef.value?.pointer;
80+
// call your method on `pointer`
81+
});
82+
</script>
83+
```

Diff for: src/components/interaction/OlInteractionPointer.vue

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<template>
2+
<slot></slot>
3+
</template>
4+
5+
<script setup lang="ts">
6+
import { inject, watch, onMounted, onUnmounted, shallowRef } from "vue";
7+
import Pointer, { type Options } from "ol/interaction/Pointer";
8+
import type Map from "ol/Map";
9+
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
10+
import { useOpenLayersEvents } from "@/composables/useOpenLayersEvents";
11+
import type { MapBrowserEvent } from "ol";
12+
13+
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
14+
defineOptions({
15+
inheritAttrs: false,
16+
});
17+
18+
const emit = defineEmits<{
19+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20+
(e: "down", data: MapBrowserEvent<any>): void;
21+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
22+
(e: "move", data: MapBrowserEvent<any>): void;
23+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
24+
(e: "up", data: MapBrowserEvent<any>): void;
25+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
26+
(e: "drag", data: MapBrowserEvent<any>): void;
27+
}>();
28+
29+
const props =
30+
defineProps<
31+
Omit<
32+
Options,
33+
| "handleDownEvent"
34+
| "handleDragEvent"
35+
| "handleMoveEvent"
36+
| "handleUpEvent"
37+
>
38+
>();
39+
40+
const map = inject<Map>("map");
41+
const properties = usePropsAsObjectProperties(props);
42+
43+
const pointer = shallowRef(
44+
new Pointer({
45+
...properties,
46+
handleDownEvent: (e) => {
47+
emit("down", e);
48+
return true;
49+
},
50+
handleDragEvent: (e) => {
51+
emit("drag", e);
52+
return true;
53+
},
54+
handleMoveEvent: (e) => {
55+
emit("move", e);
56+
},
57+
handleUpEvent: (e) => {
58+
emit("up", e);
59+
return true;
60+
},
61+
}),
62+
);
63+
64+
useOpenLayersEvents(pointer, ["change:active"]);
65+
66+
watch(pointer, (newVal, oldVal) => {
67+
map?.removeInteraction(oldVal);
68+
map?.addInteraction(newVal);
69+
map?.changed();
70+
});
71+
72+
onMounted(() => {
73+
map?.addInteraction(pointer.value);
74+
});
75+
76+
onUnmounted(() => {
77+
map?.removeInteraction(pointer.value);
78+
});
79+
80+
defineExpose({
81+
pointer,
82+
});
83+
</script>

Diff for: src/components/interaction/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import OlInteractionLink from "./OlInteractionLink.vue";
77
import OlInteractionSelect from "./OlInteractionSelect.vue";
88
import OlInteractionDraw from "./OlInteractionDraw.vue";
99
import OlInteractionModify from "./OlInteractionModify.vue";
10+
import OlInteractionPointer from "./OlInteractionPointer.vue";
1011
import OlInteractionSnap from "./OlInteractionSnap.vue";
1112
import OlInteractionTransform from "./OlInteractionTransform.vue";
1213
import type { Vue3OpenlayersGlobalOptions } from "@/types";
@@ -20,6 +21,7 @@ function install(app: App, options?: Vue3OpenlayersGlobalOptions) {
2021
app.component("OlInteractionSelect", OlInteractionSelect);
2122
app.component("OlInteractionDraw", OlInteractionDraw);
2223
app.component("OlInteractionModify", OlInteractionModify);
24+
app.component("OlInteractionPointer", OlInteractionPointer);
2325
app.component("OlInteractionSnap", OlInteractionSnap);
2426
app.component("OlInteractionTransform", OlInteractionTransform);
2527

@@ -44,6 +46,7 @@ export {
4446
OlInteractionSelect,
4547
OlInteractionDraw,
4648
OlInteractionModify,
49+
OlInteractionPointer,
4750
OlInteractionSnap,
4851
OlInteractionTransform,
4952
};

Diff for: src/demos/PointerDemo.vue

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<template>
2+
<ol-map
3+
:loadTilesWhileAnimating="true"
4+
:loadTilesWhileInteracting="true"
5+
style="height: 400px"
6+
>
7+
<ol-view
8+
ref="view"
9+
:center="center"
10+
:zoom="zoom"
11+
:projection="projection"
12+
/>
13+
14+
<ol-tile-layer>
15+
<ol-source-osm />
16+
</ol-tile-layer>
17+
18+
<ol-interaction-pointer
19+
@down="log('⬇️ down', $event)"
20+
@up="log('⬆️ up', $event)"
21+
@move="log('🚗 move', $event)"
22+
@drag="log('🤚🏽 drag', $event)"
23+
/>
24+
</ol-map>
25+
</template>
26+
27+
<script setup lang="ts">
28+
import type { MapBrowserEvent } from "ol";
29+
import { ref } from "vue";
30+
31+
const center = ref([40, 40]);
32+
const projection = ref("EPSG:4326");
33+
const zoom = ref(8);
34+
35+
const log = (type: string, event: MapBrowserEvent<UIEvent>) => {
36+
console.log(type, event);
37+
};
38+
</script>

Diff for: vite.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export default defineConfig({
126126
"ol/interaction/Draw": "Draw",
127127
"ol/interaction/DragBox": "DragBox",
128128
"ol/interaction/Modify": "Modify",
129+
"ol/interaction/Pointer": "Pointer",
129130
"ol/style/Circle": "CircleStyle",
130131
"ol/style/Fill": "Fill",
131132
"ol/style/Stroke": "Stroke",

0 commit comments

Comments
 (0)