1

I'm looking for a way to make marker shadows work with the "visual refresh" that's coming to Google Maps, but can't seem to.

I suppose the following is the recommended way to do it: https://developers.google.com/maps/tutorials/customizing/custom-markers

Can anyone see the marker shadows in the examples on that tutorial? I can't.

What are you guys doing to make this work?

Thanks in advance!

Alexandre Martini
  • 389
  • 1
  • 4
  • 14
  • 2
    possible duplicate of [Shadows on Google Maps visualRefresh](http://stackoverflow.com/questions/18470063/shadows-on-google-maps-visualrefresh) – geocodezip Sep 19 '13 at 21:07
  • hi, thanks for trying to help, but i don't see it as a duplicate because i'm asking if people are seeing shadows in the examples on that tutorial... do you see them? – Alexandre Martini Sep 20 '13 at 18:59
  • There are no shadows in the documentation anymore. Full Stop. – geocodezip Sep 20 '13 at 19:03

2 Answers2

1

One option for adding shadows to post visual refresh Google Maps Javascript API v3 maps:

  1. create a Custom Overlay to hold the shadow image attached to the "overlayShadow" pane
  2. add one for every marker

Add markers with shadows like this:

var marker = new google.maps.Marker({
    position: myLatLng,
    map: map,
    icon: getMarkerImage(beach[4]),
    shape: iconShape,
    title: beach[0],
    zIndex: Math.round(myLatLng.lat()*-100000)<<5
});
var shadow = new MarkerShadow(myLatLng, iconShadow, map);
marker.bindTo('map',shadow,'map');

MarkerShadow code (modified from Google's Custom Overlay example):

MarkerShadow.prototype = new google.maps.OverlayView();
/** @constructor */
function MarkerShadow(position, options, map) {

  // Initialize all properties.
  this.posn_ = position;
  this.map_ = map;
  if (typeof(options) == "string") {
    this.image = options;
  } else {
    this.options_ = options;
    if (!!options.size) this.size_ = options.size;
    if (!!options.url)  this.image_ = options.url;
  }

  // Define a property to hold the image's div. We'll
  // actually create this div upon receipt of the onAdd()
  // method so we'll leave it null for now.
  this.div_ = null;

  // Explicitly call setMap on this overlay.
  this.setMap(map);
}
/**
 * onAdd is called when the map's panes are ready and the overlay has been
 * added to the map.
 */
MarkerShadow.prototype.onAdd = function() {
  // if no url, return, nothing to do.
  if (!this.image_) return;
  var div = document.createElement('div');
  div.style.borderStyle = 'none';
  div.style.borderWidth = '0px';
  div.style.position = 'absolute';

  // Create the img element and attach it to the div.
  var img = document.createElement('img');
  img.src = this.image_;
  img.style.width = this.options_.size.x + 'px';
  img.style.height = this.options_.size.y +'px';
  img.style.position = 'absolute';
  div.appendChild(img);

  this.div_ = div;

  // Add the element to the "overlayLayer" pane.
  var panes = this.getPanes();
  panes.overlayShadow.appendChild(div);
};

MarkerShadow.prototype.draw = function() {
  // if no url, return, nothing to do.
  if (!this.image_) return;
  // We use the coordinates of the overlay to peg it to the correct position 
  // To do this, we need to retrieve the projection from the overlay.
  var overlayProjection = this.getProjection();

  var posn = overlayProjection.fromLatLngToDivPixel(this.posn_);

  // Resize the image's div to fit the indicated dimensions.
  if (!this.div_) return;
  var div = this.div_;
  if (!!this.options_.anchor) {
   div.style.left = Math.floor(posn.x-this.options_.anchor.x) + 'px';
   div.style.top = Math.floor(posn.y-this.options_.anchor.y) + 'px';
  }
  if (!!this.options_.size) {
   div.style.width = this.size_.x + 'px';
   div.style.height = this.size_.y + 'px';
  }
};

// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
MarkerShadow.prototype.onRemove = function() {
  if (!this.div_) return;
  this.div_.parentNode.removeChild(this.div_);
  this.div_ = null;
};
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • Related question: [Google Maps API v3 add shadow on clicked marker](http://stackoverflow.com/questions/34176330/google-maps-api-v3-add-shadow-on-clicked-marker) – geocodezip Dec 09 '15 at 12:26
1

Why not create an extra marker with lower z-index?

createMarkerShadow = function(map, data) {
        var latLng = new google.maps.LatLng(data.latitude, data.longitude);
        var markerShadow = new google.maps.Marker({
            clickable: false,
            position: latLng,
            map: map,
            icon:{
                url: '/frontend/img/icons/google-map-marker-shadow.svg',
                //The size image file.
                size: new google.maps.Size(225, 120),
                //The point on the image to measure the anchor from. 0, 0 is the top left.
                origin: new google.maps.Point(0, 0),
                //The x y coordinates of the anchor point on the marker. e.g. If your map marker was a drawing pin then the anchor would be the tip of the pin.
                anchor: new google.maps.Point(115, 82)
            },
            zIndex: (Math.round(latLng.lat()*-100000)<<5)-1
        });

        return markerShadow;
    };


setMarkerShadows = function (map, locations, bound) {
    for (var i = 0; i < locations.length; i++) {
        var data = locations[i];
        var markerShadow = createMarkerShadow(map, data);

        bound.extend(markerShadow.getPosition());
    }
};

bound = new google.maps.LatLngBounds();
  • I've just read this on Google's docs: "Marker shadows were removed in version 3.14 of the Maps JavaScript API. Any shadows specified programmatically will be ignored." Probably it will affect the code of this answer :/ – funder7 Jan 03 '21 at 20:43