Map event listeners
vanilla.html
react.html
vue.html
common.css
common.ts
variables.css
variables.ts
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./index.ts"
></script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
<link rel="stylesheet" href="./common.css" />
<link rel="stylesheet" href="../variables.css" />
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/react-dom@17/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="react, typescript"
type="text/babel"
src="./index.tsx"
></script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
<link rel="stylesheet" href="./common.css" />
<link rel="stylesheet" href="../variables.css" />
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./index.ts"
></script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
<link rel="stylesheet" href="./common.css" />
<link rel="stylesheet" href="../variables.css" />
</head>
<body>
<div id="app"></div>
</body>
</html>
.events {
width: 200px;
padding: 8px;
display: flex;
flex-direction: column;
}
.events:nth-child(2)::before {
content: '';
position: relative;
top: -8px;
display: block;
border-top: 1px solid #5c5e661a;
justify-content: center;
width: 90%;
margin: 0 auto;
}
.events__title {
font-size: 14px;
width: 184px;
height: 20px;
padding: 0 8px;
align-content: center;
color: #7b7d85;
}
.events__list {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
}
.events__item {
color: #050d33;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 20px;
padding: 8px 8px 8px 36px;
border-radius: 8px;
align-content: center;
background-repeat: no-repeat;
background-position: 5% 50%;
}
.events__item.update {
background-image: url('./update.svg');
}
.events__item.resize {
background-image: url('./resize.svg');
}
.events__item.scrollZoom {
background-image: url('./scrollZoom.svg');
}
.events__item.drag {
background-image: url('./drag.svg');
}
.events__item.mouseRotate {
background-image: url('./mouseRotate.svg');
}
.events__item.mouseTilt {
background-image: url('./mouseTilt.svg');
}
.events__item.click {
background-image: url('./click.svg');
}
.events__item.dblClick {
background-image: url('./dblClick.svg');
}
.events__item.rightDblClick {
background-image: url('./rightDblClick.svg');
}
.events__item.mouseMove {
background-image: url('./mouseMove.svg');
}
.events__item.mouseEnter {
background-image: url('./mouseEnter.svg');
}
.events__item.mouseLeave {
background-image: url('./mouseLeave.svg');
}
.events__item.mouseDown {
background-image: url('./mouseDown.svg');
}
.events__item_active {
background-color: var(--color-interact-component-chkd-hover);
}
.infoWindow {
width: 300px;
padding: 15px;
padding-left: 50px;
position: relative;
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.9);
font-size: 16px;
}
.infoWindow__icon {
width: 30px;
height: 30px;
position: absolute;
top: 50%;
left: 10px;
transform: translateY(-50%);
}
import type {BehaviorType} from '@mappable-world/mappable-types';
import type lodash from 'lodash';
declare global {
// @ts-ignore
const _: typeof lodash;
}
// An array of enabled map behaviors
export const BEHAVIOR: BehaviorType[] = ['drag', 'scrollZoom', 'dblClick', 'mouseRotate', 'mouseTilt'];
/* Initialize a custom EventListener control
Assign a value to it after loading the map api */
export let EventListener = null;
type mapEventsType = {
title: string;
events: {
update: boolean;
resize: boolean;
};
};
type domEventsType = {
title: string;
events: {
click: boolean;
fastClick: boolean;
dblClick: boolean;
rightClick: boolean;
rightDblClick: boolean;
mouseMove: boolean;
mouseEnter: boolean;
mouseLeave: boolean;
mouseDown: boolean;
};
};
type behaviorEventsType = {
title: string;
events: {
scrollZoom: boolean;
drag: boolean;
mouseRotate: boolean;
mouseTilt: boolean;
};
};
type EventListenerProps = mapEventsType | domEventsType | behaviorEventsType;
// Wait for the api to load to access the entity system (MMapComplexEntity)
mappable.ready.then(() => {
class EventListenerClass extends mappable.MMapComplexEntity<EventListenerProps> {
private _element: HTMLDivElement;
private _detachDom: () => void;
// Method for create a DOM control element
_createElement() {
const {title, events} = this._props;
// Create a root element
const rootElement = document.createElement('div');
rootElement.classList.add('events');
// Create an events title element
const eventsTitle = document.createElement('div');
eventsTitle.textContent = title;
eventsTitle.classList.add('events__title');
rootElement.appendChild(eventsTitle);
// Create an events list element
const eventsList = document.createElement('ul');
eventsList.classList.add('events__list');
rootElement.appendChild(eventsList);
// Iterate through the events and create list items
for (let event in events) {
const eventElement = document.createElement('li');
eventElement.classList.add('events__item', event);
eventElement.textContent = event;
eventElement.id = event;
eventsList.appendChild(eventElement);
}
return rootElement;
}
// Method that is used when updating the parameters of control
_onUpdate() {
const {events} = this._props;
for (let event in events) {
const eventElement = document.getElementById(event);
if (!eventElement) return;
if (events[event]) {
eventElement.classList.add('events__item_active');
} else {
eventElement.classList.remove('events__item_active');
}
}
}
// Method for attaching the control to the map
_onAttach() {
this._element = this._createElement();
this._detachDom = mappable.useDomContext(this, this._element, this._element);
}
// Method for detaching control from the map
_onDetach() {
this._detachDom();
this._detachDom = null;
this._element = null;
}
}
EventListener = EventListenerClass;
});
:root {
--color-interact-component-chkd-hover: rgba(18, 45, 178, 0.06);
}
import type {MMapLocationRequest} from '@mappable-world/mappable-types';
export const LOCATION: MMapLocationRequest = {
center: [55.5358, 25.3176], // starting position [lng, lat]
zoom: 11.7 // starting zoom
};