Question

I'm looking to create a google map using the javascript API. I can create the map, customise the look and add the default markers to the maps but...

I need to create markers which look like the following:

Google map markers

I know I can do it by creating multiple images for each item but as there could be hundreds of markers on the page at one time, I ideally don't want to create images for each individual marker.

Each marker will have a number that refers to an item in a list.

Is it possible to create them using HTML and CSS as this will allow me to create a additional colour markers at a later date much easier.

Was it helpful?

Solution

Instead of a Marker you may create a custom overlay

It will give you the option to use HTML, via CSS it's not difficult to create an element that is styled like your example-images.

A possible implementation:

function HtmlMarker(map,position,content,cssText){
  this.setValues({
                  position:position,
                  container:null,
                  content:content,
                  map:map,
                  cssText:cssText
                 });

  this.onAdd = function() {
    var that      = this,container = document.createElement('div'),
        content   = this.get('content'),
        cssText   = this.get('cssText')
                     ||'border-color:#fff;background:#fff;color:#000;';
    container.className='HtmlMarker';
    container.style.cssText = cssText;

    google.maps.event.addDomListener(container,'click',
         function(){google.maps.event.trigger(that,'click');});
    if(typeof content.nodeName!=='undefined'){
      container.appendChild(content);
    }
    else{
      container.innerHTML=content;
    }


    container.style.position='absolute';
    this.set('container',container)
    this.getPanes().floatPane.appendChild(container);
  }

  this.draw=function(){
    var pos       = this.getProjection()
                     .fromLatLngToDivPixel(this.get('position')),
        container = this.get('container');
    container.style.left = pos.x - (container.offsetWidth/2)+ 'px';
    container.style.top  = pos.y - (container.offsetHeight) + 'px';
  }

  this.onRemove = function() {
    this.get('container').parentNode.removeChild(this.get('container'));
    this.set('container',null)
  }
}

The overlay-div will have the className HtmlMarker , use this class to apply the basic layout:

  .HtmlMarker {
      font-size:18px;
      margin-top:-6px;/*!*/
      padding: 4px 10px;
      position: relative;
      display:inline-block;
      cursor:pointer;
  }
  .HtmlMarker:after {
      position: absolute;
      display: inline-block;
      border-bottom: 6px solid transparent;/*!*/
      border-top: 6px solid;/*!*/
      border-top-color:inherit;
      border-right: 6px solid transparent;/*!*/
      border-left: 6px solid transparent;/*!*/
      left: 50%;
      margin-left:-6px;/*!*/
      top:100%;
      content:'';
  }

The 6px/-6px in the properties marked with the /*!*/ define the size of the tip, when you modify the size you must modify all these values.

The first 3 arguments of HtmlMarker() (map,position,content) should be self-explaining. The 4th argument cssText expects a cssText that gives you the option to apply custom CSS.

To define a background-color you must set background and border-color to the same value:, e.g.:

border-color:white;background:white;

more properties may be added when you want to, but basically you may use the stylesheet to apply more styles(except the color, this value of course should be compatible with the background)

A click-event is already implemented, more features are possible too, e.g. a draggable-option.

Demo: http://jsfiddle.net/doktormolle/5arST/

OTHER TIPS

It's not an easy question, mostly depends on the approximate number of markers you have t display at once. Marker drawables can be defined only as one of the following:

  • URL of an image
  • Pre-defined Symbol path (such as circle or different arrows)
  • A string that is valid SVG format

When you have to display hundreds or thousands of marker instances, it's not evident whether is better to use image or SVG. Images are problematic both because you have to manually create or generate them, and they have to be transferred through the network (note that the browser caches them so it won't pull the same marker image twice). SVG on the other hand must be drawn in the client side every time it appears, making it very computationally heavy for the client. I experienced serious lag when displaying more than a thousand basic SVGs (a simple cross shape) on a map, while it didn't have a problem with rendering the default marker icon.

I would recommend SVG under 500 markers and image over this approximate number.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top