Skip to content

Commit

Permalink
Add support for draggable marker.
Browse files Browse the repository at this point in the history
  • Loading branch information
francois2metz committed Apr 27, 2024
1 parent 03a508a commit 8ea2e32
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 3 deletions.
47 changes: 47 additions & 0 deletions docs/examples/marker-draggable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Marker draggable
//
// A map with a draggable marker
<template>
<mgl-map
:map-style="style"
:center="center"
:zoom="zoom"
height="300px"
>
<mgl-navigation-control />
<mgl-marker
:coordinates="coordinates"
:draggable="draggable"
color="#cc0000"
@dragstart="console.log('dragstart')"
@drag="console.log('drag')"
@dragend="console.log('dragend')"
/>
</mgl-map>
<button @click="draggable = !draggable">Toggle draggable state</button>
</template>

<script setup>
import {
MglMap,
MglNavigationControl,
MglMarker
} from '@indoorequal/vue-maplibre-gl';
import { ref } from 'vue';
const style = 'https://api.maptiler.com/maps/streets/style.json?key=cQX2iET1gmOW38bedbUh';
const center = [12.550343, 55.665957];
const zoom = 8;
const coordinates = [12.550343, 55.665957];
const draggable = ref(true);
</script>

<style lang="scss">
@import "maplibre-gl/dist/maplibre-gl.css";
@import "@indoorequal/vue-maplibre-gl/dist/vue-maplibre-gl.css";
body {
margin: 0;
}
html, body, #app { height: 100%; }
</style>
54 changes: 51 additions & 3 deletions lib/components/marker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,66 @@ import { mapSymbol, markerSymbol } from "@/lib/types";

export default /*#__PURE__*/ defineComponent({
name: "MglMarker",
emits: [
/**
* Fired when dragging starts
*/
"dragstart",
/**
* Fired while dragging
*/
"drag",
/**
* Fired when the marker is finished being dragged
*/
"dragend"
],
props: {
/**
* Marker coordinates
*/
coordinates: {
type: [Object, Array] as unknown as PropType<LngLatLike>,
required: true,
},
/**
* The offset in pixels as a PointLike object to apply relative to the element's center. Negatives indicate left and up.
*/
offset: [Object, Array] as PropType<PointLike>,
/**
* A string indicating the part of the Marker that should be positioned closest to the coordinate set via Marker#setLngLat. Options are 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', and 'bottom-right'. Default Value ts 'center'
*/
anchor: String as PropType<PositionAnchor>,
/**
* The color to use for the default marker if options.element is not provided. The default is light blue. Default Value ts '#3FB1CE'
*/
color: String as PropType<string>,
// draggable : Boolean as PropType<boolean>, todo implement feature
/**
* A boolean indicating whether or not a marker is able to be dragged to a new position on the map. Default Value ts false
*/
draggable: Boolean as PropType<boolean>,
/**
* The max number of pixels a user can shift the mouse pointer during a click on the marker for it to be considered a valid click (as opposed to a marker drag). The default is to inherit map's clickTolerance. Default Value ts 0
*/
clickTolerance: Number as PropType<number>,
/**
* The rotation angle of the marker in degrees, relative to its respective rotationAlignment setting. A positive value will rotate the marker clockwise. Default Value ts 0
*/
rotation: Number as PropType<number>,
/**
* map aligns the Marker's rotation relative to the map, maintaining a bearing as the map rotates. viewport aligns the Marker's rotation relative to the viewport, agnostic to map rotations. auto is equivalent to viewport. Default Value ts 'auto'
*/
rotationAlignment: String as PropType<"map" | "viewport" | "auto">,
/**
* map aligns the Marker to the plane of the map. viewport aligns the Marker to the plane of the viewport. auto automatically matches the value of rotationAlignment. Default Value ts 'auto'
*/
pitchAlignment: String as PropType<"map" | "viewport" | "auto">,
/**
* The scale to use for the default marker if options.element is not provided. The default scale corresponds to a height of 41px and a width of 27px. Default Value ts 1
*/
scale: Number as PropType<number>,
},
setup(props, { slots }) {
setup(props, { slots, emit }) {
const map = inject(mapSymbol)!,
opts: MarkerOptions = Object.keys(props)
.filter(
Expand All @@ -54,11 +98,15 @@ export default /*#__PURE__*/ defineComponent({
marker.setLngLat(props.coordinates).addTo(map.value!);
provide(markerSymbol, shallowRef(marker));

marker.on("dragstart", () => emit("dragstart"));
marker.on("drag", () => emit("drag"));
marker.on("dragend", () => emit("dragend"));

watch(
() => props.coordinates,
(v) => marker.setLngLat(v),
);
// watch(() => props.draggable, v => marker.setDraggable(v || false));
watch(() => props.draggable, v => marker.setDraggable(v));
watch(
() => props.offset,
(v) => marker.setOffset(v || [0, 0]),
Expand Down

0 comments on commit 8ea2e32

Please sign in to comment.