I want to add a custom HTML element (that can become transparent dynamically) instead of a marker.
Basically my html object would be a cirle (or rounded pin) with a picture of users in the middle.
I have imagined different solutions:
place a label (containing HTML) covering the marker which visibility would be set to none
work with overlays
hard way: replace the marker with a PNG image that I should compose dynamically with some sort of library superimposing two images (one geometric and the other user picture).
Anyway I can't figure out what to do and how to do it.
Thanks, Stefano
I realize that you've developed your own solution in the comments but for anyone looking for a simpler solution to this problem I would suggest looking into the Marker With Label library.
The library adds a DOM element along with each marker (designed to add a text label ect to each item, personally I've always used it for numbering), that could easily be utilized to allow for an image to be placed at each location. This could be used instead of the marker as Dr.Molle suggests, or in addition to. You are able to use the offset option to place the element in relation to the marker and so using z-index could overlay the image on top.
Here is a simple example of using an image as a label, taken from here:
<style type="text/css">
.labels {
color: white;
background-color: red;
font-family: "Lucida Grande", "Arial", sans-serif;
font-size: 10px;
text-align: center;
width: 100px;
white-space: nowrap;
}
</style>
var latLng = new google.maps.LatLng(49.47805, -123.84716);
var homeLatLng = new google.maps.LatLng(49.47805, -123.84716);
var map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 12,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var pictureLabel = document.createElement("img");
pictureLabel.src = "home.jpg";
var marker = new MarkerWithLabel({
position: homeLatLng,
map: map,
draggable: true,
raiseOnDrag: true,
labelContent: pictureLabel,
labelAnchor: new google.maps.Point(50, 0),
labelClass: "labels", // the CSS class for the label
labelStyle: {opacity: 0.50}
});
var iw = new google.maps.InfoWindow({
content: "Home For Sale"
});
google.maps.event.addListener(marker, "click", function (e) { iw.open(map, this); });
To position and overlay the image use the following options:
labelStyle: {top: "-30px", left: "-3px"},
labelZIndex: 2
Note that the positions are arbitrary and may require some tweaking. As an aside (and unrelated), I really like the idea of using an avatar in addition to the marker.
Related
I'm trying to add a pulse effect to a custom map marker. When I add the animation CSS to the map marker, the animation works, but it seems to be bound by the dimensions of the container that it gets put in, cutting off the pulse effect. I'm trying to figure out how to add a div around the marker image so that I can control its size and possibly other attributes. Here's how I initialize the map:
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: new google.maps.LatLng(20, -80),
disableDefaultUI: true
});
var features = [
{
position: new google.maps.LatLng(20, -80)
}
];
// Create markers
features.forEach(function(feature) {
var marker = new google.maps.Marker({
position: feature.position,
icon: 'images/map-pin.svg',
map: map
});
});
}
That places the pin on the map and with CSS I add the animation:
img[src*='map-pin-solid.svg'] {
animation: pulse 1.5s ease-out infinite;
}
That works, but as mentioned, the pin is bound by it's container div, so the pulse animation gets cut off at the boundaries of the div. I'd like to add my own container div around it so I can control its size. I've been searching other answers on this site and around the web, and I think I should be using a custom overlay to do this, but looking at that code I have no idea where to even begin. I'd basically like to be inserting something like this as the marker
<div class = "marker">
<img src = "images/map-pin.svg" />
</div>
How do I do this?
Turns out I can size the marker this way to make room for the animation:
var image = {
url: 'images/map-marker.svg',
size: new google.maps.Size(100, 100),
origin: new google.maps.Point(-20, -20),
anchor: new google.maps.Point(30, 50),
scaledSize: new google.maps.Size(30, 30)
};
Can we add some notes, a string, while making overlay shapes with google maps API? Like If I draw a circle around my home to indicate High alert area within circle with a note on it, so a person seeing the circle will know quickly, or can I just use color scheme to do this? Please, if you guys have some solution?
Yes you can do it.
Such a thing could be achieved with InfoWindow class, see also InfoWindowOptions object about details what options you can modify
and also check the google documentation sample.
The most important option of the InfoWindowOptions object is content
Type: string|Node
Content to display in the InfoWindow. This can be
an HTML element, a plain-text string, or a string containing HTML. The
InfoWindow will be sized according to the content. To set an explicit
size for the content, set content to be a HTML element with that size.
So let's have a look on how InfoWindow is displayed:
Initialize map (new google.maps.Map)
Initialize InfoWindow
Open the InfoWindow with the open() method
If you want to draw a circle you can use Circle class , see also CircleOptions object to see what options you can adjust. It is easy to draw circles on the map - you just need to instantiate a circle(new google.maps.Circle) and pass the map in the options object.
Check the following demo code and let me know if something is not clear.
function init() {
var center = new google.maps.LatLng(33.53625, -111.92674);
var contentString = '<div id="content">' +
'<div id="bodyContent">' +
'<p>Beware this is my home :)</p>' +
'</div>' +
'</div>';
/*-------------------
MAP
-------------------*/
var map = new google.maps.Map(document.getElementById('map'), {
center: center,
zoom: 13,
scrollwheel: false
});
/*-------------------
CIRCLE
-------------------*/
var circle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.4,
map: map,
center: center,
radius: 200
});
/*-------------------
INFO WINDOW
-------------------*/
var infoWindowIsOpen = true;
var infowindow = new google.maps.InfoWindow({
content: contentString,
position: center
});
google.maps.event.addListener(infowindow, 'closeclick', function() {
infoWindowIsOpen = false;
togglePopupButton.innerHTML = "Show Popup"
});
infowindow.open(map);
/*-------------------
TOGGLE INFO WINDOW BUTTON
-------------------*/
var togglePopupButton = document.getElementById('togglePopup');
togglePopupButton.addEventListener('click', function() {
infoWindowIsOpen = !infoWindowIsOpen;
if (infoWindowIsOpen) {
infowindow.open(map);
togglePopupButton.innerHTML = 'Hide Popup';
} else {
infowindow.close();
togglePopupButton.innerHTML = 'Show Popup';
}
});
}
.as-console-wrapper{
display:none !important;
}
<script async defer type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&callback=init"></script>
<div id="map" style="width:400px;height:150px;float:left"></div>
<button id="togglePopup" style="float:left">Hide Popup</button>
There are many calls for help with the maps API where a blank white div is undesirable. In my case it's desirable.
I know how to make a map appear.
map.setCenter(new google.maps.LatLng(latitude, longitude));
I know how to make directions appear.
directionsService.route(request, function(result, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
Occasionally I just want the map element to "go white." Later I want to put a map or directions back in there.
I've tried this:
$('#map').empty();
It works, but after that I can never make a map appear again. What's the correct way?
I suppose I could make and delete map instances but this bug report says each destroyed map instance leaks 2MB memory, and Google officially discourages the practice (here and here). I'd really rather not overlay a white rectangle, or make the map display:none. Is there no better way?
(My application is a map next to an address entry form. When sufficient detail has been entered, a map automatically appears. If the field contents are deleted, the map goes blank again.)
I would just set the map div's innerHTML to "".
document.getElementById('map_canvas').innerHTML = "";
(but $("#map_canvas").empty(); works as well)
Once you do that you need to recreate and reinitialize the map object.
map = new google.maps.Map(document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
proof of concept fiddle
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var displayMap = true;
google.maps.event.addDomListener(document.getElementById('btn'), 'click', function() {
if (displayMap) {
document.getElementById('map_canvas').innerHTML = "";
} else {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
displayMap = !displayMap;
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input type="button" id="btn" value="toggle map" />
<div id="map_canvas"></div>
Set the map visibility to hidden.
Better yet, use a class.
CSS:
.map-hide {
visibility: hidden;
}
jQuery:
$('#map').addClass('map-hide');
$('#map').removeClass('map-hide');
JavaScript (IE10+):
document.getElementById("map").classList.add('map-hide');
document.getElementById("map").classList.remove('map-hide');
Add the class to blank the map. Remove it when rendering the map.
Adding and removing a class is better in case multiple parts of the code turn visibility on or off for different reasons.
Setting a map's visibility to hidden is better than setting its display to none, which can permanently ruin map rendering. I saw one clue to this in the docs about Map.fitBounds() breaking.
I would like to display name of the place next to the marker as shown in the below screen shot. Currently I don't need rest of the details appearing in Google Maps. All I care is that name of the hotel should appear along with the Marker.
Example: Courtyard Marriott Hotel - Google Maps link which clearly shows the name.
I have created demo jsFiddle (doesn't show the label)
var googleMap;
var hotelLocation = {
lat: 43.681592,
lng: -79.713612
};
var mapCenter = hotelLocation; //{ lat: 43.690497, lng: -79.966831 };
google.maps.event.addDomListener(window, 'resize', function() {
//https://stackoverflow.com/questions/8792676/center-google-maps-v3-on-browser-resize-responsive
var center = googleMap.getCenter();
google.maps.event.trigger(googleMap, "resize");
googleMap.setCenter(center);
});
function InitializeGoogleMaps() {
//http://www.latlong.net/convert-address-to-lat-long.html
//90 Biscayne Crescent, Brampton, ON - Address of Hotel - { lat: 43.681592, lng: -79.713612 };
googleMap = new google.maps.Map(document.getElementById('map'), {
zoom: 14,
center: mapCenter
});
var marker = new google.maps.Marker({
position: hotelLocation,
map: googleMap,
title: 'Courtyard by Marriott'
});
}
InitializeGoogleMaps();
I have gone thru many search terms (as I am not sure what is the right word for this label and gone thru Maps Marker API too) but so far no luck. I think below thread seems to be on the same lines however I am hoping that there will be built in support inside Google maps rather then going for extra lib.
How to display a label next to a Marker for Google Maps?
It is more likely for comment, but excuse me (I can not comment yet ;))
Positioning can be done over margin, instead of counting by marker size.
It is tiny update of ndd jsFiddle in comment here https://stackoverflow.com/a/34145265/2686510
http://jsfiddle.net/6t3pyr94/
Someone could find it helpful to have css freedom of label position.
.map-marker-label {
position: absolute;
color: red;
font-size: 16px;
font-weight: bold;
/* Use margin to position the text */
/* top, left position is the place of marker position */
margin-top: -45px;
margin-left: 20px;
}
You can use pixelOffset:
pixelOffset: new google.maps.Size(100,140);
The result would be:
var marker = new google.maps.Marker({
position: hotelLocation,
map: googleMap,
title: 'Courtyard by Marriott',
pixelOffset: new google.maps.Size(100,140);
});
I read all the similar questions but mine is slightly different. The first time a JQuery Mobile dialog is displayed, the map loads fine inside the usual map_canvas div, but if the dialog is reloaded (i.e. go back and click on the button to open the dialog again), it is displayed only partially, zoomed out to a 3 or 4 and centered around the div's top-left corner.
There is no change in the div size (which is explicitly set) and for good measure a google.maps.event.trigger(map, 'resize'); is called.
I also tried to initialize the map after the dialog is shown but the result is the same.
Button code:
$("#dest-map-button").click(function() {
initializeMap(job_id,"map_canvas");
}
);
Function:
function initializeMap(job_id, map_div){
var pos = arrJobs[job_id].lat_lng.split(',');
var job_pos = new google.maps.LatLng(pos[0],pos[1]);
var driverLatLng = lat_lng.split(',');
var driver_pos = new google.maps.LatLng(driverLatLng[0],driverLatLng[1]);
var myOptions = {
zoom: 18,
center: driver_pos,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
}
map = new google.maps.Map(document.getElementById(map_div), myOptions);
var marker = new google.maps.Marker({
position: job_pos,
map: map,
title: "Job"
});
var marker2 = new google.maps.Marker({
position: driver_pos,
map: map,
title: "X",
});
google.maps.event.trigger(map, 'resize');
}
HTML:
<div data-role="page" id="dialog-destination-map" data-theme="e">
<div data-role="content">
<div id="map_canvas" style="height:300px; width:300px; position: relative; margin: 0px auto;">
map_canvas
</div>
</div>
</div>
Any ideas?
EDIT: this question seems describing exactly the same problem: JQuery Mobile & Google Maps Glitch
But the solution provided (caching) can't be used here as the map might need to change
After trying everything else, I finally stumbled upon the pageshow event. Calling initializeMap after all the page transitions are done rather than when clicking the button solved the problem:
$('#dialog-destination-map').live('pageshow',function(event){
initializeMap(job_id,"map_canvas");
}
);
I still wonder how come it was working at the first load then...
I Agree with #peter .. You do not need to create map on each pageshow event.. Instead, try this:
$(document).on("pagebeforechange", function()
{
if(mapObj){
center = mapObj.getCenter();
}
});
$("#mapPage").bind("pageshow", function()
{
google.maps.event.trigger(mapObj, "resize");
if(center)mapObj.setCenter(center);
});
var driverLatLng is being initialized with lat_lng.split(','); which hasn't been declared before.
You don't need to create a new map each time you visit the page. Create the map beforehand, e.g. on pageinit. On pageshow: google.maps.event.trigger(mapObj, "resize");