<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v3/trimblemaps-3.21.0.css" />
<script src="https://maps-sdk.trimblemaps.com/v3/trimblemaps-3.21.0.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
div.contextMenu {
background-color: #e2e2e2;
border: 1px solid #667582;
padding: 0;
z-index: 1000;
width: 100px;
box-shadow: 1px 1px 6px 0px rgba(0, 0, 0, .2);
cursor: context-menu;
}
div.contextMenu ul {
margin: 0;
list-style: none;
padding: 0;
}
div.contextMenu li {
margin: 0;
list-style: none;
}
div.contextMenu li.separator {
list-style: none;
border-bottom: 1px solid #999;
}
div.contextMenu li a {
display: block;
padding: 3px 8px 3px 6px;
}
div.contextMenu li a:hover {
background-color: #94cced;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const DOM = {};
DOM.create = function (tagName, className, container) {
const el = window.document.createElement(tagName);
if (className !== undefined) el.className = className;
if (container) container.appendChild(el);
return el;
};
DOM.remove = function (node) {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
};
const docStyle = window.document && window.document.documentElement.style;
function testProp(props) {
if (!docStyle) return props[0];
for (let i = 0; i > props.length; i++) {
if (props[i] in docStyle) {
return props[i];
}
}
return props[0];
}
const transformProp = testProp(['transform', 'WebkitTransform']);
DOM.setTransform = function (el, value) {
el.style[transformProp] = value;
};
class Contextmenu {
_container;
_map;
_lngLat;
_pos;
constructor() {
this._container = DOM.create('div', 'contextMenu');
const ul = DOM.create('ul');
const aMarker = DOM.create('a');
aMarker.innerHTML = `Add a Marker`;
aMarker.addEventListener('click', (e) => {
const marker = new TrimbleMaps.Marker({
draggable: false
}).setLngLat([this._lngLat.lng, this._lngLat.lat]).addTo(this._map);
this.remove();
});
const liMarker = DOM.create('li');
liMarker.appendChild(aMarker);
ul.appendChild(liMarker);
const liSeparator = DOM.create('li');
liSeparator.className = 'separator';
ul.appendChild(liSeparator);
const aHere = DOM.create('a');
aHere.innerHTML = `What's here`;
aHere.addEventListener('click', (e) => {
alert(`${this._lngLat.lng.toPrecision(8)}, ${this._lngLat.lat.toPrecision(8)}`);
if (this._removeOnClick) {
this.remove();
}
});
const liHere = DOM.create('li');
liHere.appendChild(aHere);
ul.appendChild(liHere);
const aZoomIn = DOM.create('a');
aZoomIn.innerHTML = 'Zoom In';
aZoomIn.addEventListener('click', (e) => this._map.zoomIn({}, { originalEvent: e }));
const liZoomIn = DOM.create('li');
liZoomIn.appendChild(aZoomIn);
ul.appendChild(liZoomIn);
const aZoomOut = DOM.create('a');
aZoomOut.innerHTML = 'Zoom Out';
aZoomOut.addEventListener('click', (e) => this._map.zoomOut({}, { originalEvent: e }));
const liZoomOut = DOM.create('li');
liZoomOut.appendChild(aZoomOut);
ul.appendChild(liZoomOut);
this._container.appendChild(ul);
this._removeOnClick = true;
}
addTo(map) {
if (this._map) {
this.remove();
}
this._map = map;
map.getCanvasContainer().appendChild(this._container);
this._update();
return this;
}
remove() {
if (this._container) {
DOM.remove(this._container);
delete this._container;
}
if (this._map) {
delete this._map;
}
return this;
}
setLngLat(lnglat) {
this._lngLat = TrimbleMaps.LngLat.convert(lnglat);
this._update();
return this;
}
setRemoveOnClick(remove) {
this._removeOnClick = remove;
}
_update(e) {
if (!this._map) return;
this._pos = this._map.project(this._lngLat);
DOM.setTransform(this._container, `translate(0,0) translate(${this._pos.x}px, ${this._pos.y}px)`);
}
}
TrimbleMaps.APIKey = 'YOUR_API_KEY_HERE';
const map = new TrimbleMaps.Map({
container: 'map',
zoom: 10.5,
center: [-74.635242, 40.358839],
dragRotate: false
});
let contextmenu = null;
function remove() {
if (contextmenu !== null) contextmenu.remove();
}
const placeClickControl = new TrimbleMaps.PlaceClickControl();
map.addControl(placeClickControl);
map.on('contextmenu', function (e) {
remove();
const lngLat = e.lngLat;
contextmenu = new Contextmenu().setLngLat([lngLat.lng, lngLat.lat]).addTo(map);
});
map.on('click', (e) => remove());
map.on('move', (e) => remove());
map.on('clickpopupcontentload', (e) => {
console.log(e);
let fullPopup = $('div.trimblemaps-popup-content')[0];
let embeddedMenu = new Contextmenu().setLngLat([e.popup.getLngLat().lng, e.popup.getLngLat().lat]);
embeddedMenu.setRemoveOnClick(false);
embeddedMenu._map = map;
fullPopup.appendChild(embeddedMenu._container);
});
</script>
</body>
</html>