Mission Construction
For this train, our customized Google Map demo will stay on GitHub (not on CodePen). Right here’s the venture construction:
map/ ├── index.html ├── img/ │ ├── deal with.svg │ ├── modal-fax.svg │ ├── modal-lat-long.svg │ ├── modal-pin.svg │ ├── modal-tel.svg │ └── pin.svg ├── major.css └── major.js
1. Scaffolding the Mission
Earlier than we begin creating our venture (that may seem like a mini app) there are some things that we’ve got to think about.
Seize a Google Maps API key
As a primary and obligatory factor, we must always get a Google Maps API key. To take action, we have to comply with these directions and arrange a venture within the Google Cloud Console with the Maps JavaScript API enabled.
For this demonstration, we’ll borrow an API key from an outdated but nonetheless well-liked collection known as The Google Maps API For Designers. There’s additionally an related demo from the place we will extract the API.
warning
This demo API key has utilization limits! Ensure to register in your personal API key and substitute the one within the instance.
Final however not least, as quickly as you arrange such a venture within the Google Cloud Console, it’s all the time sensible to limit the related API. For instance, you might need a single venture and an API that you just share throughout all of your web site purchasers. In such a case, you possibly can limit the API requests to particular web sites.
Seize Some Knowledge
To create the markers and make our venture as life like as potential, we’ll want some real-world information. With this in thoughts, as beforehand talked about, we’ll take 13 of the Adobe workplace places and pin them on our map.
As we’ll see later, every location wants to incorporate its latitude and longitude. As this information isn’t accessible on Adobe’s contact web page, we’ll use the LangLong.internet web site to retrieve their coordinates. A few of the coordinates may not be completely correct, however you get the purpose.
Seize Some Icons
To boost the demo look, we’ll want some icons.
Envato Parts offers lots of of various map and navigation icons for our wants. On this case, we’ll go along with an icon set that follows a stuffed line fashion. As we noticed from the venture construction, the chosen SVG icons will stay contained in the img
folder.
Listed here are the SVG icons we’ll use in our venture:
Embrace Bootstrap Recordsdata
Lastly, though not required, to hurry up the event course of we’ll additionally embrace Bootstrap in our venture by following the CDN method, as described on this web page.
2. Outline the Web page Markup
Now that we’ve got the whole lot arrange, let’s have a look at our markup.
Required Recordsdata
Under you possibly can see the beginning markup with all of the required Bootstrap recordsdata, our recordsdata, and the script
tag for the Maps JavaScript API:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta title="viewport" content material="width=device-width, initial-scale=1" /> <title>A easy instance displaying tips on how to construct a trendy Google Map with a number of markers</title> <hyperlink href="https://cdn.jsdelivr.internet/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="nameless" /> <hyperlink rel="stylesheet" href="major.css" /> </head> <physique> <!-- content material right here --> <script src="https://cdn.jsdelivr.internet/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="nameless"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBSJRUNeSfHkH_ChC38jKTvjc2V7QQcOYs&language=en&callback=initMap" async></script> <script src="major.js"></script> </physique> </html>
Simply check out the script
tag for the Maps JavaScript API. You’ll see two attributes:
- The
src
attribute contains the bottom name to the Maps JavaScript API together with three parameters: two required and one non-obligatory. The requiredkey
parameter shops our API key as retrieved from the Google Cloud Console. The non-obligatorylanguage
parameter determines the map’s language (location names, labels, and so forth.). The requiredcallback
parameter defines the title of the worldwide perform that may fireplace as soon as the Maps JavaScript API finishes its load. - The
async
parameter tells the browser to asynchronously obtain and execute the script.
Customized Google Map Format
Earlier than having a more in-depth have a look at the web page parts, let’s focus on the structure necessities.
- On cellular screens (<768px), the structure might be like this:
- On medium and huge screens (≥768px), there might be two equal-width columns:
- In every case, the map will cowl the window top.
Right here’s the related markup stuffed with Bootstrap helper courses:
<div class="container-fluid"> <div class="row align-items-center"> <div class="col-md-6 mt-5 mb-3"> <h1 class="mb-4"> A few of <a href="https://www.adobe.com/about-adobe/contact/workplaces.html" class="text-body" goal="_blank">Adobe's workplace places</a> </h1> <div class="block"> <h2 class="mb-3">North America</h2> <div class="row"> <div class="col-sm-6 mb-2"> <div class="d-flex align-items-center"> <img width="24" top="24" src="img/deal with.svg" alt="" class="me-2" /> <a href="" class="location text-body" data-index="0">Company headquarters</a> </div> </div> <div class="col-sm-6 mb-2"> <div class="d-flex align-items-center"> <img width="24" top="24" src="img/deal with.svg" alt="" class="me-2" /> <a href="" class="location text-body" data-index="1">Los Angeles</a> </div> </div> </div> <hr /> </div> <!-- extra blocks right here --> </div> <div class="col-md-6 p-0"> <div id="map" class="vh-100"></div> </div> </div> </div>
Most significantly, discover two issues:
- Every location hyperlink, which represents an Adobe location, comes with the
data-index
attribute. Maintain this attribute in thoughts, as we’ll use it afterward. - There’s an empty factor with the
map
ID. It will embrace the map contents and might be generated by JavaScript.
3. Add the JavaScript
At this level, we’re able to construct the core performance of our customized Google Map venture. Let’s do it!
Retailer Areas
We captured the places within the markup, however we additionally want them in JavaScript. So, let’s retailer them below an array like this:
const pins = [ { location: "North America", name: "Corporate headquarters", address: "345 Park Avenue <br> San Jose, CA 95110-2704", tel: "408-536-2800", fax: "408-537-6000", lat: 37.33078, long: -121.892357, }, { location: "North America", name: "Los Angeles", address: "(former Magento office) <br> 3640 Holdrege Ave <br> Los Angeles, CA 90016", lat: 34.01989, long: -118.37811, }, // more locations here ];
Understand that we protect the order through which the places seem each within the markup and object. A location with the data-index="0"
within the markup denotes that the identical location needs to be within the first place of the pins
array.
Be aware: in a real-world situation, there would in all probability be a backend language to handle all places in a single place. For instance, if you happen to’re conversant in WordPress and the ACF PRO plugin, you’ll in all probability have a versatile content material or a repeater discipline the place you place all places. Inside it, there might be additional fields for managing the situation particulars. Particularly for grabbing the coordinates of every location, you possibly can have a Google Map discipline. Then, by way of the wp_localize_script()
you’re capable of go the places within the JavaScript and construct an object much like the one we’ve got right here.
Initialize Customized Google Map
Arising subsequent, we’ll initialize the map by the initMap()
that we confirmed earlier than.
Our map could have the next customizations:
- It’ll be centered in London, UK.
- It’ll have
zoom: 3
to see as many places as potential by default. - We’ll customise its default kinds by this software, however you possibly can all the time go for cloud-based map styling. Most notably, we’ll change the default shade of the water like this:
With all of the above in thoughts, right here’s the beginning physique of our perform:
// London, UK const middle = { lat: 51.507351, lng: -0.127758 }; const kinds = [ { featureType: "poi", stylers: [ { visibility: "off" } ] }, { featureType: "water", stylers: [ { color: "#39C3FC" } ] } ]; perform initMap() { const map = new google.maps.Map(doc.getElementById("map"), { middle, kinds, zoom: 3 }); }
Create Google Map Markers
Contained in the initMap()
perform, we’ll additionally name the createMarkers()
perform for creating the situation markers:
perform initMap() { // map declaration right here createMarkers(map); }
Inside this perform, we’ll do the next issues:
- Initialize an information window that may show details about a marker every time somebody clicks on it.
- Change the default marker icon with a customized SVG one.
- Loop by the places and place them on the map based mostly on their coordinates. Additionally, make them seem with a DROP animation.
- Retailer every marker occasion within the
markers
array. We’ll see why later.
Right here’s the perform declaration:
perform createMarkers(map) { const infowindow = new google.maps.InfoWindow(); const markerIcon = { url: "img/pin.svg", scaledSize: new google.maps.Measurement(40, 40) }; for (let i = 0; i < pins.size; i++) { const marker = new google.maps.Marker({ place: { lat: pins[i].lat, lng: pins[i].lengthy }, map, icon: markerIcon, animation: google.maps.Animation.DROP }); markers.push(marker); } }
Toggle Data Window
Contained in the createMarkers()
perform, we’ll additionally register a click on
occasion for every marker.
perform createMarkers(map) { ... for (let i = 0; i < pins.size; i++) { // marker right here google.maps.occasion.addListener(marker, "click on", perform () { infowindow.setContent(createInfoWindowContent(pins[i])); map.setCenter(marker.getPosition()); infowindow.open(map, marker); const targetLocation = doc.querySelector(`[data-index="${i}"]`); if (doc.querySelector(".location.energetic")) { doc .querySelector(".location.energetic") .classList.take away(activeClass); } targetLocation.classList.add(activeClass); scroll({ high: targetLocation.offsetTop, conduct: "easy" }); }); } }
Every time a person clicks on a marker, we’ll carry out the next actions:
- Populate the information window’s content material with contents related to this marker because of the
createInfoContent()
perform. - Set the map’s middle based mostly on the coordinates of this marker.
- Present the information window.
- Take away the
energetic
class from any related location hyperlink, if any. - Discover the situation hyperlink whose index matches the index of this marker and provides it the
energetic
class. It will give the goal hyperlink a blue background shade.
- Easy scroll to the corresponding location hyperlink.
Populate Data Window
As we mentioned, the job of the createInfoContent()
perform might be to feed the information window with the contents of the clicked marker.
We’ll use simple markup to show the contents of every marker. On condition that some places don’t all the time have all the main points, we’ll apply some checks to make sure that our markup received’t be bloated.
Right here’s the perform declaration:
perform createInfoWindowContent(pin) { let phoneString = ""; let faxString = ""; let latLongString = ""; let addressString = ""; if (pin.tel) { phoneString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" top="24" src="https://webdesign.tutsplus.com/tutorials/img/modal-tel.svg" alt=""> ${pin.tel} </p> `; } if (pin.fax) { faxString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" top="24" src="img/modal-fax.svg" alt=""> ${pin.fax} </p> `; } if (pin.lat && pin.lengthy) { latLongString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" top="24" src="img/modal-lat-long.svg" alt=""> ${pin.lat}, ${pin.lengthy} </p> `; } if (pin.deal with) { addressString = ` <div class="d-flex"> <img class="me-2" width="24" top="24" src="img/modal-pin.svg" alt=""> ${pin.deal with} </div> `; } const contentString = ` <h3 class="fs-4 textual content">${pin.title}</h3> <hr> ${phoneString} ${faxString} ${latLongString} ${addressString} `; return contentString; }
Location Hyperlinks
We mentioned what ought to occur when a marker is clicked. However we additionally want to use some performance when the other occurs. In different phrases, we need to be certain that every time a person clicks on a location hyperlink, the corresponding marker might be clicked.
One other perform, the showLocations()
one, might be liable for dealing with this performance. This will even stay contained in the initMap()
perform.
So, every time a location hyperlink is clicked, we’ll carry out the next actions:
- Cancel its default conduct.
- Take away the
energetic
class from any location hyperlink, if any. - Add the
energetic
class to this hyperlink. - Easy scroll to the map.
- Discover the marker whose index matches the index of this hyperlink and set off its
click on
occasion. We’re capable of goal the required marker as a result of we’ve saved it in a earlier step contained in themarkers
array.
Right here’s the perform definition:
perform showLocations() { const places = doc.querySelectorAll(".location"); places.forEach((location) => { location.addEventListener("click on", perform (e) { e.preventDefault(); if (doc.querySelector(".location.energetic")) { doc .querySelector(".location.energetic") .classList.take away(activeClass); } location.classList.add(activeClass); scroll({ high: doc.getElementById("map").offsetTop, conduct: "easy" }); new google.maps.occasion.set off(markers[this.dataset.index], "click on"); }); }); }
Conclusion
And we’re performed! This was fairly an extended journey, however I hope that you just loved it and that it has helped improve your abilities relating to the Google Maps JavaScript API.
As soon as once more, don’t overlook to place your individual key for stay venture testing! Right here’s the venture hyperlink.
Issues don’t cease right here. We are able to proceed enhancing/extending this venture by doing quite a few issues, for example:
- Put into desk marker clusters for grouping markers. It is a good addition, particularly for circumstances the place there are plenty of markers.
- Make this venture dynamic by utilizing WordPress and ACF PRO, as defined in a couple of sections above. Relying on how this venture goes, I’ll in all probability come again with such a tutorial sooner or later 🙂
- Prohibit the map boundaries to keep away from displaying a grey space throughout dragging or zooming out.
As all the time, thanks loads for studying!