Add CSS styled marker to google maps

40,627

Solution 1

Use RichMarker for Google Maps v3 - usage:

curMarker = new RichMarker({
    position: new google.maps.LatLng(position),
    map: map,
    content: '<div id="foo">Bar</div>'
});

JSFiddle example.

Solution 2

Here's a modified version of the pulse animator you mentioned that I'm using that works. Basically you create an overlay (https://developers.google.com/maps/documentation/javascript/customoverlays) that you then position by attaching to a marker point.

To have the pin and animation created from CSS I believe you'll need to set the pin image blank and to the correct size with something like this if you'd like it to be clickable through the marker.

var image = {
  url: '/images/blank.png',
  size: new google.maps.Size(100, 39),
  origin: new google.maps.Point(0, 0),
  anchor: new google.maps.Point(50, 39),
  };

Then make sure the overlay is drawn on the correct pane

var pane = this.getPanes().overlayImage; (contains the marker foreground images.)

My implementation provided below is slightly different because I decided to use a pin image and only the animation part. I'm going to draw on the overlayShadow so the animation goes behind the image I use for the marker.

JS

var animatedOverlay;

// Define the animated overlay, derived from google.maps.OverlayView
function PinAnimation(opt_options) {
    this.setValues(opt_options);
    var div = this.div_ = document.createElement('div');
    div.id = 'holder';

    var span = this.span_ = document.createElement('span');
    span.className = 'pulse';
    div.appendChild(span);
};

PinAnimation.prototype = new google.maps.OverlayView;

PinAnimation.prototype.onAdd = function() {

     //Overlay shadow puts the animation behind the pin
     var pane = this.getPanes().overlayShadow;
     pane.appendChild(this.div_);

     // Ensures the PinAnimation is redrawn if the text or position is changed.
     var me = this;
     this.listeners_ = [
          google.maps.event.addListener(this, 'position_changed',
               function() { me.draw(); }),
     ];
};

// Implement onRemove
PinAnimation.prototype.onRemove = function() {
     this.div_.parentNode.removeChild(this.div_);

     // PinAnimation is removed from the map, stop updating its position/any other listeners added.
     for (var i = 0, I = this.listeners_.length; i < I; ++i) {
          google.maps.event.removeListener(this.listeners_[i]);
     }
};

// Set the visibility to 'hidden' or 'visible'.
PinAnimation.prototype.hide = function() {
    if (this.div_) {
        this.div_.style.visibility = 'hidden';
    }
};
PinAnimation.prototype.show = function() {
    if (this.div_) {
        this.div_.style.visibility = 'visible';
    }
};

// Implement draw
PinAnimation.prototype.draw = function() {
    var topPadding = 0;
    var sizeHeight = 50
    var sizeWidth = sizeHeight;
    var centerX = sizeWidth/2;
    var centerY = sizeHeight/2;

     var projection = this.getProjection();
     var position = projection.fromLatLngToDivPixel(this.get('position'));
     var div = this.div_;
//Adjust overlay position to be centered over the point
     div.style.left = position.x-centerX + 'px';
     div.style.top = position.y-topPadding-centerY + 'px';
     div.style.display = 'block';
};

//Set marker and draw overlay
function setMarker(location) {

    var maps_location = new google.maps.LatLng(location.latitude, location.longitude);

    var marker = new google.maps.Marker({
        position: map_location,
        map: map,
        icon: marker.png,
        title: 'Hello World!'
        });

    animatedOverlay = new PinAnimation({
        map: map
    });
    animatedOverlay.bindTo('position', marker, 'position');
    animatedOverlay.show();
}

CSS

#holder {
height: 50px;
width: 50px;
position: absolute;
transform: rotateX(55deg);
background: transparent;
}
.pulse {
    border: 10px solid #5bc0de;
    background: transparent;
    -webkit-border-radius: 50%;
    -moz-border-radius: 50%;
    border-radius: 50%;
    height: 50px;
    width: 50px;
    -webkit-animation: pulse 1s ease-out;
    -moz-animation: pulse 1s ease-out;
    animation: pulse 1s ease-out;
    -webkit-animation-iteration-count: infinite;
    -moz-animation-iteration-count: infinite;
    animation-iteration-count: infinite;
    position: absolute;
    z-index: 1;
    opacity: 0;
}
@-moz-keyframes pulse {
 0% {
    -moz-transform: scale(0);
    opacity: 0.0;
 }
 25% {
    -moz-transform: scale(0);
    opacity: 0.1;
 }
 50% {
    -moz-transform: scale(0.1);
    opacity: 0.3;
 }
 75% {
    -moz-transform: scale(0.5);
    opacity: 0.5;
 }
 100% {
    -moz-transform: scale(1);
    opacity: 0.0;
 }
}
@-webkit-keyframes pulse {
 0% {
    -webkit-transform: scale(0);
    opacity: 0.0;
 }
 25% {
    -webkit-transform: scale(0);
    opacity: 0.1;
 }
 50% {
    -webkit-transform: scale(0.1);
    opacity: 0.3;
 }
 75% {
    -webkit-transform: scale(0.5);
    opacity: 0.5;
 }
 100% {
    -webkit-transform: scale(1);
    opacity: 0.0;
 }
}
Share:
40,627
kurrodu
Author by

kurrodu

Updated on May 04, 2020

Comments

  • kurrodu
    kurrodu about 4 years

    Can someone please advise how I could add this animated marker to the below google maps API.

    The below is the standard google maps api code with option to give image source for the marker (icon).

    function initialize() {
      var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
      var mapOptions = {
        zoom: 4,
        center: myLatlng
      }
      var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
      var marker = new google.maps.Marker({
          position: myLatlng,
          map: map,
          icon: marker.png,         //Option for setting the marker source
          title: 'Hello World!'
      });
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
    
    • Chris
      Chris over 10 years
      Im pretty sure that you need to add an image to the icon parameter, however that pin is drawn completely in CSS. You can add animations to the image but unsure if you can draw it completely. The other option is to use the google map marker object [link] w3schools.com/googleAPI/google_maps_overlays.asp or heres a good start [link] sitepoint.com/embellishing-your-google-map-with-css3-and-jqu‌​ery
    • duncan
      duncan over 10 years
      It's not clear if your problem is making the marker CSS styled or if you want it animated when it's added to the map. If the latter you can specify the animation: google.maps.Animation.DROP property in your marker's options when creating it. See developers.google.com/maps/documentation/javascript/examples‌​/…
    • kurrodu
      kurrodu over 10 years
      The problem I have is displaying the css styled marker (with pulse animation) on google maps.
    • kurrodu
      kurrodu over 10 years
      I've just found that someone has already implemented the css styled marker in the below link (scroll to the bottom of the page to see that working). atmyprime.com Trying to figure out how this has been implemented.
  • Wasyster
    Wasyster almost 7 years
    How can I add this to my angular 2 project? I got an error on line 37 RichMarker.prototype = new google.maps.OverlayView(); window['RichMarker'] = RichMarker; richmarker.js:37 Uncaught Reference Error: google is not defined at richmarker.js:37
  • Angel Romero
    Angel Romero almost 7 years
    @Wasyster maybe you need add "richmarker.js" library. You find here github.com/googlemaps/v3-utility-library/blob/master/richmar‌​ker/…