Skip to content

Commit

Permalink
feat(ol-interaction-mouse-wheel-zoom): provide new interaction to dis…
Browse files Browse the repository at this point in the history
…able / customize mouse zoom behavior

closes #356
  • Loading branch information
d-koppenhagen committed Aug 9, 2024
1 parent cf67e75 commit 8846176
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 26 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ export const config: UserConfig = {
text: "ol-interaction-modify",
link: "/componentsguide/interactions/modify/",
},
{
text: "ol-interaction-mouse-wheel-zoom",
link: "/componentsguide/interactions/mousewheelzoom/",
},
{
text: "ol-interaction-pointer",
link: "/componentsguide/interactions/pointer/",
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/animations.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
Animations,
Animations,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/geometries.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
Geometries,
Geometries,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/interactions.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
Interactions,
Interactions,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
82 changes: 82 additions & 0 deletions docs/componentsguide/interactions/mousewheelzoom/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# ol-interaction-mouse-wheel-zoom

> Define the mouse wheel zoom behaviour
[[toc]]

## Demo

<script setup>
import MouseWheelZoomDemo from "@demos/MouseWheelZoomDemo.vue"
</script>

<ClientOnly>
<MouseWheelZoomDemo/>
</ClientOnly>

## Setup

<!--@include: ../../interactions.plugin.md-->

## Usage

| Plugin Usage | Explicit Import |
|-------------------------------------|:--------------------------------------------:|
| `<ol-interaction-mouse-wheel-zoom>` | `<Interactions.OlInteractionMouseWheelZoom>` |

::: code-group

<<< ../../../../src/demos/MouseWheelZoomDemo.vue

:::

## Properties

### Props from OpenLayers

Properties are passed-trough from OpenLayers directly.
Their types and default values can be checked-out [in the official OpenLayers docs](https://openlayers.org/en/latest/apidoc/module-ol_interaction_MouseWheelZoom.html).
Only some properties deviate caused by reserved keywords from Vue / HTML.
This deviating props are described in the section below.

### Deviating Properties

None.

## Events

You have access to all Events from the underlying interaction.
Check out [the official OpenLayers docs](https://openlayers.org/en/latest/apidoc/module-ol_interaction_MouseWheelZoom.html) to see the available events tht will be fired.

```html
<ol-interaction-mouse-wheel-zoom @error="handleEvent" />
```

## Methods

You have access to all Methods from the underlying interaction.
Check out [the official OpenLayers docs](https://openlayers.org/en/latest/apidoc/module-ol_interaction_MouseWheelZoom.html) to see the available methods.

To access the source, you can use a `ref()` as shown below:

```vue
<template>
<!-- ... -->
<ol-interaction-mouse-wheel-zoom ref="interactionRef" />
<!-- ... -->
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type MouseWheelZoom from "ol/interaction/MouseWheelZoom";
const interactionRef = ref<{ mouseWheelZoom: MouseWheelZoom } | null>(null);
onMounted(() => {
const mouseWheelZoom: MouseWheelZoom = interactionRef.value?.mouseWheelZoom;
// call your method on `mouseWheelZoom`
});
</script>
```


3 changes: 1 addition & 2 deletions docs/componentsguide/layers.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Layers,// [!code focus]
Sources,
} from "vue3-openlayers";

Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/map.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:5]
Map,
Map,// [!code focus]
Layers,
Sources,
} from "vue3-openlayers";
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/mapcontrols.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
MapControls,
MapControls,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/sources.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
Sources,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
3 changes: 1 addition & 2 deletions docs/componentsguide/styles.plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { createApp } from "vue";
import App from "./App.vue";

import {
// [!code focus:6]
Map,
Layers,
Sources,
Styles,
Styles,// [!code focus]
} from "vue3-openlayers";

const app = createApp(App);
Expand Down
47 changes: 47 additions & 0 deletions src/components/interaction/OlInteractionMouseWheelZoom.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<slot></slot>
</template>

<script setup lang="ts">
import { inject, watch, onMounted, onUnmounted, computed } from "vue";
import MouseWheelZoom, { type Options } from "ol/interaction/MouseWheelZoom";
import type Map from "ol/Map";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
const props = withDefaults(defineProps<Options>(), {
onFocusOnly: false,
maxDelta: 1,
duration: 250,
timeout: 80,
useAnchor: true,
constrainResolution: false,
});
const map = inject<Map>("map");
const properties = usePropsAsObjectProperties(props);
const mouseWheelZoom = computed(() => new MouseWheelZoom(properties));
watch(mouseWheelZoom, (newVal, oldVal) => {
map?.removeInteraction(oldVal);
map?.addInteraction(newVal);
map?.changed();
});
onMounted(() => {
// remove the default MouseWheelZoom interaction if available
map?.getInteractions().forEach((interaction) => {
if (interaction instanceof MouseWheelZoom) {
map?.removeInteraction(interaction);
}
});
map?.addInteraction(mouseWheelZoom.value);
});
onUnmounted(() => {
map?.removeInteraction(mouseWheelZoom.value);
});
defineExpose({
mouseWheelZoom,
});
</script>
3 changes: 3 additions & 0 deletions src/components/interaction/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import OlInteractionModify from "./OlInteractionModify.vue";
import OlInteractionPointer from "./OlInteractionPointer.vue";
import OlInteractionSnap from "./OlInteractionSnap.vue";
import OlInteractionTransform from "./OlInteractionTransform.vue";
import OlInteractionMouseWheelZoom from "./OlInteractionMouseWheelZoom.vue";
import type { Vue3OpenlayersGlobalOptions } from "@/types";

function install(app: App, options?: Vue3OpenlayersGlobalOptions) {
Expand All @@ -24,6 +25,7 @@ function install(app: App, options?: Vue3OpenlayersGlobalOptions) {
app.component("OlInteractionPointer", OlInteractionPointer);
app.component("OlInteractionSnap", OlInteractionSnap);
app.component("OlInteractionTransform", OlInteractionTransform);
app.component("OlInteractionMouseWheelZoom", OlInteractionMouseWheelZoom);

if (options) {
app.provide("ol-options", options);
Expand All @@ -49,4 +51,5 @@ export {
OlInteractionPointer,
OlInteractionSnap,
OlInteractionTransform,
OlInteractionMouseWheelZoom,
};
32 changes: 32 additions & 0 deletions src/demos/MouseWheelZoomDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
Zoom is only active when the platform-modifier-key (the meta-key on Mac,
ctrl-key otherwise) is pressed (no additional key e. g. shift-key) .
<ol-map
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
style="height: 400px"
>
<ol-view
ref="view"
:center="center"
:zoom="zoom"
:projection="projection"
/>

<ol-tile-layer>
<ol-source-osm />
</ol-tile-layer>

<ol-interaction-mouse-wheel-zoom :condition="condition" />
</ol-map>
</template>

<script setup>
import { ref } from "vue";
import { platformModifierKeyOnly } from "ol/events/condition";
const center = ref([-102.13121, 40.2436]);
const projection = ref("EPSG:4326");
const zoom = ref(5);
const condition = ref(platformModifierKeyOnly);
</script>
22 changes: 12 additions & 10 deletions tests/MapPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { expect, Locator, Page } from "@playwright/test";

type Point = [x: number, y: number];

type Modifier = "Alt" | "Control" | "Meta" | "ControlOrMeta" | "Shift";

export class MapPage {
readonly getStartedLink: Locator;
readonly gettingStartedHeader: Locator;
Expand Down Expand Up @@ -43,6 +45,14 @@ export class MapPage {
}
}

async zoomWithMouseWheel(deltaY = 5, modifier?: Modifier) {
const boundingBox = await this.canvasBBox();
await this.page.mouse.move(boundingBox.x + 100, boundingBox.y + 100);
await this.page.keyboard.down(modifier);
await this.page.mouse.wheel(0, -deltaY);
await this.page.keyboard.up(modifier);
}

async checkCanvasScreenshot() {
await expect(this.mapCanvas()).toHaveScreenshot({
timeout: 8000,
Expand All @@ -53,11 +63,7 @@ export class MapPage {
return await this.mapCanvas().boundingBox();
}

async dragOnCanvas(
start: Point,
end: Point,
modifiers?: ("Alt" | "Control" | "Meta" | "Shift")[],
) {
async dragOnCanvas(start: Point, end: Point, modifiers?: Modifier[]) {
const boundingBox = await this.canvasBBox();

if (boundingBox) {
Expand Down Expand Up @@ -105,11 +111,7 @@ export class MapPage {
}
}

async clickOnCanvas(
point: Point,
modifiers?: ("Alt" | "Control" | "Meta" | "Shift")[],
dblClick = false,
) {
async clickOnCanvas(point: Point, modifiers?: Modifier[], dblClick = false) {
dblClick
? await this.mapCanvas().dblclick({
position: {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions tests/interactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ test.describe("ol-interaction-dragrotatezoom", () => {
});
});

test.describe("ol-interaction-mouse-wheel-zoom", () => {
test("should zoom the map view when platform modifier key pressed", async ({
page,
}) => {
const map = new MapPage(page);
await map.goto("/componentsguide/interactions/mousewheelzoom/");
await map.waitUntilReady();
await map.waitUntilCanvasLoaded();
await map.zoomWithMouseWheel(100, "ControlOrMeta");
await map.checkCanvasScreenshot();
});
});

test.describe("ol-interaction-link", () => {
test("should update the URL after loading", async ({ page }) => {
const map = new MapPage(page);
Expand Down

0 comments on commit 8846176

Please sign in to comment.