Skip to content

Commit 7a77e99

Browse files
authored
feat(ol-interaction-synchronize): Add synchronize interaction (#441)
Allows to snychronize between two or more maps see: https://viglino.github.io/ol-ext/examples/misc/map.interaction.synchronize.html
1 parent 9baf35b commit 7a77e99

File tree

6 files changed

+145
-0
lines changed

6 files changed

+145
-0
lines changed

docs/.vitepress/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ export const config: UserConfig = {
404404
text: "ol-interaction-snap",
405405
link: "/componentsguide/interactions/snap/",
406406
},
407+
{
408+
text: "ol-interaction-synchronize",
409+
link: "/componentsguide/interactions/synchronize/",
410+
},
407411
{
408412
text: "ol-interaction-transform",
409413
link: "/componentsguide/interactions/transform/",
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# ol-interaction-synchronize
2+
3+
> Synchronize interaction from ol-ext that allows synchronizing multiple maps
4+
5+
[[toc]]
6+
7+
## Demo
8+
9+
<script setup lang="ts">
10+
import SynchronizeDemo from "@demos/SynchronizeDemo.vue"
11+
</script>
12+
13+
<ClientOnly>
14+
<SynchronizeDemo/>
15+
</ClientOnly>
16+
17+
## Setup
18+
19+
<!--@include: ../../interactions.plugin.md-->
20+
21+
## Usage
22+
23+
| Plugin Usage | Explicit Import |
24+
| ----------------------------- | :--------------------------------------: |
25+
| `<ol-interaction-synchronize>` | `<Interactions.OlInteractionSynchronize>` |
26+
27+
::: code-group
28+
29+
<<< ../../../../src/demos/SynchronizeDemo.vue
30+
31+
:::
32+
33+
## Properties
34+
35+
### maps
36+
37+
- **Type**: `Array<Map>`
38+
- **Default**: `[]`
39+
- **Description**: Array of maps to synchronize with the current map
40+
41+
## Features
42+
43+
- Synchronizes view center, zoom level, and rotation between maps
44+
- Shows cursor position on all synchronized maps
45+
- Automatically handles map interactions and updates
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<slot></slot>
3+
</template>
4+
5+
<script setup lang="ts">
6+
import { inject, onMounted, onUnmounted, computed, watch, nextTick } from "vue";
7+
import Synchronize, { type Options } from "ol-ext/interaction/Synchronize";
8+
import type Map from "ol/Map";
9+
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
10+
11+
defineOptions({
12+
inheritAttrs: false,
13+
});
14+
15+
const props = withDefaults(defineProps<Options>(), {
16+
maps: () => [],
17+
});
18+
19+
const map = inject<Map>("map");
20+
const properties = usePropsAsObjectProperties(props);
21+
22+
const synchronize = computed(
23+
() =>
24+
new Synchronize({
25+
...properties,
26+
}),
27+
);
28+
29+
watch(
30+
synchronize,
31+
async (newVal, oldVal) => {
32+
if (oldVal) map?.removeInteraction(oldVal);
33+
await nextTick();
34+
if (map?.getTargetElement()) {
35+
map.addInteraction(newVal);
36+
map.changed();
37+
}
38+
},
39+
{ immediate: false }
40+
);
41+
42+
onMounted(async () => {
43+
await nextTick();
44+
if (map?.getTargetElement()) {
45+
map.addInteraction(synchronize.value);
46+
}
47+
});
48+
49+
onUnmounted(() => {
50+
map?.removeInteraction(synchronize.value);
51+
});
52+
53+
defineExpose({
54+
synchronize,
55+
});
56+
</script>

src/components/interaction/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import OlInteractionPointer from "./OlInteractionPointer.vue";
1111
import OlInteractionSnap from "./OlInteractionSnap.vue";
1212
import OlInteractionTransform from "./OlInteractionTransform.vue";
1313
import OlInteractionMouseWheelZoom from "./OlInteractionMouseWheelZoom.vue";
14+
import OlInteractionSynchronize from "./OlInteractionSynchronize.vue";
1415
import type { Vue3OpenlayersGlobalOptions } from "@/types";
1516

1617
function install(app: App, options?: Vue3OpenlayersGlobalOptions) {
@@ -29,6 +30,7 @@ function install(app: App, options?: Vue3OpenlayersGlobalOptions) {
2930
app.component("OlInteractionSnap", OlInteractionSnap);
3031
app.component("OlInteractionTransform", OlInteractionTransform);
3132
app.component("OlInteractionMouseWheelZoom", OlInteractionMouseWheelZoom);
33+
app.component("OlInteractionSynchronize", OlInteractionSynchronize);
3234

3335
if (options) {
3436
app.provide("ol-options", options);
@@ -55,4 +57,5 @@ export {
5557
OlInteractionSnap,
5658
OlInteractionTransform,
5759
OlInteractionMouseWheelZoom,
60+
OlInteractionSynchronize,
5861
};

src/demos/SynchronizeDemo.vue

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<template>
2+
<div style="display: flex; gap: 10px;">
3+
<div style="width: 400px; height: 300px;">
4+
<ol-map ref="map1" :loadTilesWhileAnimating="true" style="height: 100%">
5+
<ol-view :center="center" :zoom="zoom" />
6+
<ol-tile-layer>
7+
<ol-source-osm />
8+
</ol-tile-layer>
9+
<ol-interaction-synchronize :maps="syncMaps1" />
10+
</ol-map>
11+
</div>
12+
13+
<div style="width: 400px; height: 300px;">
14+
<ol-map ref="map2" :loadTilesWhileAnimating="true" style="height: 100%">
15+
<ol-view :center="center" :zoom="zoom" />
16+
<ol-tile-layer>
17+
<ol-source-xyz url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
18+
</ol-tile-layer>
19+
<ol-interaction-synchronize :maps="syncMaps2" />
20+
</ol-map>
21+
</div>
22+
</div>
23+
</template>
24+
25+
<script setup lang="ts">
26+
import { ref, computed } from "vue";
27+
28+
const center = ref([2226389.8158654715, 5465442.183322753]);
29+
const zoom = ref(6);
30+
31+
const map1 = ref();
32+
const map2 = ref();
33+
34+
const syncMaps1 = computed(() => map2.value?.map ? [map2.value.map] : []);
35+
const syncMaps2 = computed(() => map1.value?.map ? [map1.value.map] : []);
36+
</script>

vite.umd.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export default defineConfig({
139139
"ol-ext/featureanimation/Teleport": "Teleport",
140140
"ol-ext/featureanimation/Zoom": "Zoom$1",
141141
"ol-ext/interaction/SelectCluster": "SelectCluster",
142+
"ol-ext/interaction/Synchronize": "Synchronize",
142143
"ol-ext/interaction/Transform": "Transform$1",
143144
"ol-ext/layer/AnimatedCluster": "AnimatedCluster",
144145
"ol-ext/style/FlowLine": "FlowLine",

0 commit comments

Comments
 (0)