Add custom marker icon images

This commit is contained in:
Emanuel Mutschlechner
2020-01-06 19:05:16 +01:00
parent 4c9f08f229
commit 0650921c2f
18 changed files with 3676 additions and 2916 deletions

View File

@@ -12,5 +12,7 @@ trim_trailing_whitespace = true
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.yml] [*.yml]
indent_style = space indent_size = 2
[*.js]
indent_size = 2 indent_size = 2

2
.gitignore vendored
View File

@@ -14,6 +14,8 @@ npm-debug.log*
.eslintcache .eslintcache
.node_repl_history .node_repl_history
*.js.LICENSE
### Windows ### Windows
Thumbs.db Thumbs.db
ehthumbs.db ehthumbs.db

View File

@@ -100,6 +100,40 @@ Open a url when a marker is clicked
]) ])
``` ```
Show a custom marker icon. The URL to the icon image can be absolute or relative.
```php
@map([
'lat' => '48.134664',
'lng' => '11.555220',
'zoom' => '6',
'markers' => [[
'title' => 'Go NoWare',
'lat' => '48.134664',
'lng' => '11.555220',
'url' => 'https://gonoware.com',
'icon' => 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
]],
])
```
Additionally you may also specify the icon image size and anchor in pixels. The icon will be aligned so that the anchor point is at the marker's geographical location.
```php
@map([
'lat' => '48.134664',
'lng' => '11.555220',
'zoom' => '6',
'markers' => [[
'title' => 'Go NoWare',
'lat' => '48.134664',
'lng' => '11.555220',
'url' => 'https://gonoware.com',
'icon' => 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
'iconSize' => [20, 32],
'iconAnchor' => [0, 32],
]],
])
```
## Customization ## Customization
To adjust the height of the map use CSS: To adjust the height of the map use CSS:
@@ -126,6 +160,25 @@ Fade in by default when using Bootstrap 3.3.7 or 4+. To replicate or modify the
} }
``` ```
## Advanced Customization
The event `LaravelMapInitialized` will be dispatched when a map and its markers were initialized. The DOM element, map,
markers and service name can be accessed via the event details.
```js
window.addEventListener('LaravelMapInitialized', function (event) {
var element = event.detail.element;
var map = event.detail.map;
var markers = event.detail.markers;
var service = event.detail.service;
console.log(element, map, markers, service);
});
```
Please refer to the respective documentation for advanced customization:
* [Google Maps](https://developers.google.com/maps/documentation/javascript/tutorial)
* [OpenStreetMap](https://leafletjs.com/reference-1.6.0.html)
* [Bing Maps](https://leafletjs.com/reference-1.6.0.html)
* [MapQuest](https://leafletjs.com/reference-1.6.0.html)
* [Yandex Maps](https://tech.yandex.com/maps/jsapi/)
* [MapKit (beta)](https://developer.apple.com/documentation/mapkitjs)
## Changelog ## Changelog

View File

@@ -9,9 +9,13 @@
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^5.2.0", "cross-env": "^6.0.3",
"laravel-mix": "^2.1.14", "laravel-mix": "^5.0.1",
"leaflet-bing-layer": "^3.3.0" "leaflet-bing-layer": "^3.3.1",
"resolve-url-loader": "^3.1.0",
"sass": "^1.24.2",
"sass-loader": "^8.0.0",
"vue-template-compiler": "^2.6.11"
}, },
"browserslist": [ "browserslist": [
"last 1 version", "last 1 version",

3
public/js/index.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
{ {
"/js/index.js": "/js/index.js?id=fdadfceebf455b33ea99", "/js/index.js": "/js/index.js?id=d9b7d4fc70fe1bbcdb82",
"/css/index.css": "/css/index.css?id=81569dd7736e102f4342" "/css/index.css": "/css/index.css?id=81569dd7736e102f4342"
} }

29
resources/js/index.js vendored
View File

@@ -7,6 +7,7 @@ import mapkit from './services/mapkit';
import parser from './utils/parser'; import parser from './utils/parser';
import {isDefined, logError} from './utils/helper'; import {isDefined, logError} from './utils/helper';
import './utils/customEventPolyfill';
const createMap = (element, createMap, createMarker) => { const createMap = (element, createMap, createMarker) => {
if (!isDefined(element)) { if (!isDefined(element)) {
@@ -24,9 +25,12 @@ const createMap = (element, createMap, createMarker) => {
return; return;
} }
mapData.markers.forEach(markerData => { const markers = mapData.markers.map(markerData => createMarker(map, markerData));
createMarker(map, markerData);
}) return {
map,
markers,
};
}; };
const createMapService = service => { const createMapService = service => {
@@ -36,8 +40,23 @@ const createMapService = service => {
service.createMarker, service.createMarker,
); );
const selector = `[data-map-${service.NAME}]`; const selector = `[data-map-${service.NAME}]`;
const elements = document.querySelectorAll(selector) || []; const elements = Array.prototype.slice.call(document.querySelectorAll(selector) || []);
elements.forEach(createMapService); elements.forEach(element => {
const data = createMapService(element);
dispatchEvent(service.NAME, element, data);
});
};
const dispatchEvent = (serviceName, element, data) => {
const event = new CustomEvent('LaravelMapInitialized', {
detail: {
element: element,
map: data.map,
markers: data.markers || [],
service: serviceName,
},
});
window.dispatchEvent(event);
}; };
window.onGoogleMapsReady = () => createMapService(google); window.onGoogleMapsReady = () => createMapService(google);

View File

@@ -1,5 +1,6 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper'; import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import 'leaflet-bing-layer'; import 'leaflet-bing-layer';
import {createMarker} from '../utils/leaflet';
// TODO: locales/culture // TODO: locales/culture
@@ -28,22 +29,5 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker,
const {title, lat, lng, url} = markerData;
const marker = window.L.marker([lat, lng], {
title,
keyboard: false,
draggable: false,
});
if (url) {
marker.on('click', event => {
event.originalEvent.preventDefault();
openUrl(url);
});
}
marker.addTo(map);
},
} }

View File

@@ -27,22 +27,35 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker(map, markerData) {
const {title, lat, lng, url} = markerData; const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
const marker = new window.google.maps.Marker({ const markerOptions = {
position: new window.google.maps.LatLng(lat, lng), position: new window.google.maps.LatLng(lat, lng),
map, map,
title, title,
draggable: false, draggable: false,
// icon: { };
// url: markerConfig.mapMarkerImg,
// }, if (icon) {
}); markerOptions.icon = {
url: icon,
};
if (iconSize) {
markerOptions.icon.size = new window.google.maps.Size(...iconSize);
}
if (iconAnchor) {
markerOptions.icon.anchor = new window.google.maps.Point(...iconAnchor);
}
}
const marker = new window.google.maps.Marker(markerOptions);
if (url) { if (url) {
marker.addListener('click', () => { marker.addListener('click', () => {
openUrl(url); openUrl(url);
}); });
} }
return marker;
}, },
}; };

View File

@@ -41,13 +41,35 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker(map, markerData) {
const {title, lat, lng, url} = markerData; const {title, lat, lng, url, icon} = markerData;
const coordinate = new window.mapkit.Coordinate(lat, lng); const coordinate = new window.mapkit.Coordinate(lat, lng);
const marker = new window.mapkit.MarkerAnnotation(coordinate, {
title, const markerAnnotationOptions = {title};
});
if (url) {
markerAnnotationOptions.callout = {
calloutRightAccessoryForAnnotation: function() {
const accessoryViewRight = document.createElement('a');
accessoryViewRight.className = 'right-accessory-view';
accessoryViewRight.href = url;
accessoryViewRight.target = '_blank';
accessoryViewRight.appendChild(document.createTextNode('ⓘ'));
return accessoryViewRight;
}
};
}
if (icon) {
markerAnnotationOptions.glyphImage = {
1: icon,
};
}
const marker = new window.mapkit.MarkerAnnotation(coordinate, markerAnnotationOptions);
map.showItems([marker]); // TODO: map auto resize bugging if multiple markers map.showItems([marker]); // TODO: map auto resize bugging if multiple markers
return marker;
}, },
}; };

View File

@@ -1,4 +1,5 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper'; import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {createMarker} from '../utils/leaflet';
// TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/ // TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/
@@ -34,22 +35,5 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker,
const {title, lat, lng, url} = markerData;
const marker = window.L.marker([lat, lng], {
title,
keyboard: false,
draggable: false,
});
if (url) {
marker.on('click', event => {
event.originalEvent.preventDefault();
openUrl(url);
});
}
marker.addTo(map);
},
} }

View File

@@ -1,4 +1,5 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper'; import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {createMarker} from '../utils/leaflet';
// TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/ // TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/
@@ -31,22 +32,5 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker,
const {title, lat, lng, url} = markerData;
const marker = window.L.marker([lat, lng], {
title,
keyboard: false,
draggable: false,
});
if (url) {
marker.on('click', event => {
event.originalEvent.preventDefault();
openUrl(url);
});
}
marker.addTo(map);
},
} }

View File

@@ -21,11 +21,26 @@ export default {
return map; return map;
}, },
createMarker(map, markerData) { createMarker(map, markerData) {
const {title, lat, lng, url} = markerData; const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
const marker = new window.ymaps.Placemark([lat, lng], { const placemarkProperties = {
hintContent: title, hintContent: title,
}); };
const placemarkOptions = {};
if (icon) {
placemarkOptions.iconLayout = 'default#imageWithContent';
placemarkOptions.iconImageHref = icon;
if (iconSize) {
placemarkOptions.iconImageSize = iconSize;
}
if (iconAnchor) {
placemarkOptions.iconImageOffset = iconAnchor;
}
}
const marker = new window.ymaps.Placemark([lat, lng], placemarkProperties, placemarkOptions);
// if (url) { // if (url) {
// marker.addListener('click', () => { // marker.addListener('click', () => {
@@ -34,5 +49,7 @@ export default {
// } // }
map.geoObjects.add(marker); map.geoObjects.add(marker);
return marker;
}, },
}; };

View File

@@ -0,0 +1,15 @@
(function () {
if (window.CustomEvent) return false;
function CustomEvent(event, params) {
params = params || {
bubbles: false, cancelable: false, detail: undefined
};
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent(
event, params.bubbles, params.cancelable, params.detail
);
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();

37
resources/js/utils/leaflet.js vendored Normal file
View File

@@ -0,0 +1,37 @@
import {openUrl} from './helper';
export function createMarker(map, markerData) {
const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
const markerOptions = {
title,
keyboard: false,
draggable: false,
};
if (icon) {
const iconOptions = {
iconUrl: icon,
};
if (iconSize) {
iconOptions.iconSize = iconSize;
}
if (iconAnchor) {
iconOptions.iconAnchor = iconAnchor;
}
markerOptions.icon = window.L.icon(iconOptions);
}
const marker = window.L.marker([lat, lng], markerOptions);
if (url) {
marker.on('click', event => {
event.originalEvent.preventDefault();
openUrl(url);
});
}
marker.addTo(map);
return marker;
}

View File

@@ -23,13 +23,16 @@ const parseMarkers = element => {
return markers.map(marker => { return markers.map(marker => {
const lat = parseFloat(marker.lat); const lat = parseFloat(marker.lat);
const lng = parseFloat(marker.lng); const lng = parseFloat(marker.lng);
const {title, url} = marker; const {title, url, icon, iconSize, iconAnchor} = marker;
return { return {
title, title,
lat, lat,
lng, lng,
url, url,
icon,
iconSize,
iconAnchor,
}; };
}); });
}; };

2
webpack.mix.js vendored
View File

@@ -3,7 +3,7 @@ const mix = require('laravel-mix');
mix.setPublicPath('public') mix.setPublicPath('public')
.setResourceRoot('../') .setResourceRoot('../')
.js('resources/js/index.js', 'js') .js('resources/js/index.js', 'js')
.sass('resources/sass/index.scss', 'css', {precision: 8}) .sass('resources/sass/index.scss', 'css')
.copy('resources/img/*.png', 'public/img') .copy('resources/img/*.png', 'public/img')
.version('img'); .version('img');

6292
yarn.lock

File diff suppressed because it is too large Load Diff