Custom HTML Markers with Google Maps

Given the wealth of knowledge available on the Google Maps Javascript API it came as a surprise in our experience at Humaan that it was difficult to find information regarding one very important feature – Custom HTML Map Markers. I am sure the limited resources presently available for this feature would be plaguing plenty of designers and developers.

To provide some context as to what a custom HTML map marker is we should should start with the basics. A typical Google Map Marker is generally represented by a pin.

The API allows this marker to be customised in a variety of ways. It can be scaled, rotated, dragged and even replaced with custom images.

This is very handy in most use cases but what happens when you would like your marker to perform more complex actions? Animations and complex marker content will generally require custom HTML DOM elements. This allows them to be easily accessible and readily manipulated by Javascript or CSS.

The CustomGoogleMapMarker.js file contains the standard approach to extending an existing Javascript class.

The first function declares the new custom marker class.

There are three arguments passed to this ‘constructor’ function; the latitude and longitude coordinates as a ‘LatLng’ object, the map object reference, and an object containing arguments we want to pass into the custom HTML. The function stores these values in the class scope.

The following line extends the OverlayView class and inherits it’s methods:

The next method is the most important for our discussion. This is where the magic happens and the custom HTML is created for insertion into the map.

The crux of the method takes place once the element is created.

This line defines the container DOM element that we will eventually insert into the map.

The lines following it basically specify the attributes of the element such as class name and styles. This section is where you can specify the HTML you wish to manipulate once the custom HTML is inserted into the map.

You have the option to include more complex HTML elements and also include nesting to give greater flexibility. This will be helpful once you start styling the elements or when you run Javascript methods that target the elements.

If you wish to pass other variables to the marker element (for example, a unique selector or custom class) then you can use the ‘args’ argument.

In our example we have the option of passing a ‘marker_id’ variable within our ‘args’ object and then applying it to the HTML element.

These lines check to see of the ‘marker_id’ variable is defined. If the ‘marker_id’ is defined it then applies it to the HTML element using the dataset attributes (i.e. data-marker_id=”123″). You can copy and paste these lines to create as many attributes as is required.

This is helpful for being able to select markers from outside of the Google Map script’s scope.

For example, I could build an external filter that can show and hide markers based on their attributes. An example of a working map marker filter can be found at www.form.net.au/project/public/map/.

The next section within this class method relates to the custom marker’s click event listener. Within the callback function we can choose what to do when a user clicks on the marker.

We could add other event listeners such as ‘hover’ if the functionality is required. If we are going to be passing attributes to the HTML element using the ‘args’ object we could utilise them via Javascript selectors externally. An example would be to use a jQuery selector to apply an event listener.

To summarise, we aren’t tied to using event listeners contained within the class instance.

The last section of the method is used to position the custom marker within the map. The Google Map library contains a method to convert latitude and longitude coordinates into pixels that can be used to position the marker within the bounds of the map.

What we should keep in mind is that the left and top position pixels are taken from the top left of our custom marker HTML element. Please see the example below with the original marker still visible. You can see that the blue box is below and to the right of the coordinate.

Preferably we would like the marker to sit above and central to the actual coordinates on the map – just like a standard marker would.

To do so we need to offset the position by the appropriate height and width of the marker.

Using our blue square as an example we know that the element is 20 pixels wide by 20 pixels high. Therefore to position the element above the coordinate we need to offset the top position by 20 pixels. To offset the left position we reduce it by half of the width which is 10 pixels. This will centre the marker horizontally.

If we update our example with our offsets it would look similar to the following:

The resulting marker would then look like the following:

As is shown, the blue box now sits on top of the original marker which is exactly where we would like it to be. This positioning will obviously change depending on the content of the custom marker but it is an easy fix within the script.

So we know how the marker class works, but how do we actually add this into our map?

Luckily this is a very simple process and follows the same standard pattern for initialising any Google Map. Using a function that runs when the DOM has completed loading we create our map instance and then create the new custom marker object that is inserted into the map.

If we want to add extra attributes to our custom marker we can update the call to create the new class object by including our attributes in the third argument.

This is a fairly basic example of the opportunities available using a custom marker class but hopefully it provides enough direction for you to play with and create your own custom map markers.

Last month, a tweet by Yesenia Perez-Cruz, Senior Designer at Vox Media, caught my eye. Her tweet asked what seemed like a simple question: I see an abundance of articles about how designers can make developers lives...

From the Blog

Introducing Monty, the newest member of the Humaan family. We were blown away by the uniqueness of his experience and his passion for everything he gets his hands on. When we asked what makes him tick,…