The goal of this recipe is to practice working with Google Maps. We will integrate what we learned about working with Google Maps in this chapter and incorporate our control over the user behaviors, such as what controllers the user can use, into it. We will start digging into creating our own unsupported undocumented behaviors, such as locking the users' pan area.
Our main task in this recipe will be to take our work from the previous recipe, and instead of having the map zoom in and move around, create clean transitions between the zoomed in and zoomed out options; but as that isn't supported in a clean way through the interface, we will use external focuses. The idea is simple; we will stack up two maps on top of each other and fade in and out the top map, giving us total control over the fluidity of the transitions.
Even though we are starting from scratch, a lot of the work that we did in the last recipe is being re-used, so I strongly encourage you to go through the last recipe Adding markers and events before moving into this one.
In this recipe, we will be integrating jQuery into our work as well, to save us time on creating our own animator tool (or re-using the one that we created in the Animating independent layers recipe in Chapter 6, Bringing Static Things to Life), as it would take us away from our main topic.
In this recipe we will be creating two files. An HTML file and a JS file. Let's look into it, starting with the HTML file:
maps
API and jQuery:<!DOCTYPE html> <html> <head> <title>Google Maps Markers and Events</title> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAywwIFJPo67Yd4vZgPz4EUSVu10BLHroE&sensor=true"></script> <script src="./09.05.controls.js"></script> </head> <body onload="init();"> <div id="mapIn"></div> <div id="mapOut"></div> </body> </html>
<style> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #mapIn, #mapOut { height: 100%; width:100%; position:absolute; top:0px; left:0px } </style>
09.05.controls.js
JS file and create an init
function in it (from this point onwards the rest of the code will be in the init
function):function init(){ //rest of code in here }
var BASE_CENTER = new google.maps.LatLng(40.7142,-74.0064 ); //40.7142° N, -74.0064 E NYC var mapOut = new google.maps.Map(document.getElementById("mapOut"),{ center: BASE_CENTER, zoom: 11, mapTypeId: google.maps.MapTypeId.SATELLITE, disableDefaultUI: true }); var mapIn = new google.maps.Map(document.getElementById("mapIn"),{ center: BASE_CENTER, zoom: 14, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDefaultUI: true, panControl:true });
var aMarkers = [ {label:'New York City', local: mapOut.getCenter()}, {label:'Brooklyn', local: new google.maps.LatLng(40.648, -73.957)}, {label:'Queens', local: new google.maps.LatLng(40.732, -73.800)}, {label:'Bronx', local: new google.maps.LatLng(40.851, -73.871)}, ]; var marker; for(var i=0; i<aMarkers.length; i++){ marker = new google.maps.Marker({ position: aMarkers[i].local, map: mapOut, title: aMarkers[i].label }); google.maps.event.addListener(marker, 'click', onMarkerClicked); } function onMarkerClicked(ev){ mapIn.panTo(ev.latLng); $("#mapOut").fadeOut(1000); }
click
event to the internal map, and when you have clicked on it, you will be returned to the upper map:google.maps.event.addListener(mapIn, 'click', function() { mapIn.panTo(BASE_CENTER); $("#mapOut").fadeIn(1000); });
pan
in the upper map using the center_changed
event:google.maps.event.addListener(mapOut, 'center_changed', function() { mapOut.panTo(BASE_CENTER); //always force users back to center point in external map });
When you load the HTML file, you will find a fullscreen map that cannot be dragged. When you click on a marker, it will fade into the selected area. You can now drag the cursor around the map. The next time you click in the internal map (regular click on any area), the map will fade back to the original upper layer.
Our biggest step is the creation of two maps, one overlapping the other. We did that with some CSS magic by layering the elements and putting our top layer at the last position in the stack (we could probably use the z-index to validate it, but it worked so I didn't add that to the CSS). After that we created our two div
layers and set their CSS code. In the JavaScript code, contrary to the way we did in the last recipe, we hardcoded the values that we wanted into both the maps.
In our options for both the maps, we set the default controllers not to take effect by setting the property disableDefaultUI
to be true
, while in mapIn
we set panControl
to be true
to showcase that the map can be panned through:
var mapOut = new google.maps.Map(document.getElementById("mapOut"),{ center: BASE_CENTER, zoom: 11, mapTypeId: google.maps.MapTypeId.SATELLITE, disableDefaultUI: true }); var mapIn = new google.maps.Map(document.getElementById("mapIn"),{ center: BASE_CENTER, zoom: 14, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDefaultUI: true, panControl:true });
We can manually set all the controllers by setting a Boolean value to any of the following options:
panControl
zoomControl
mapTypeControl
streetViewControl
overviewMapControl
Our event
logic works
in the exact same way that it did in the last recipe. The only change is within the actual listeners where we switch between the maps using jQuery:
function onMarkerClicked(ev){ mapIn.panTo(ev.latLng); $("#mapOut").fadeOut(1000); } google.maps.event.addListener(mapIn, 'click', function() { mapIn.panTo(BASE_CENTER); $("#mapOut").fadeIn(1000); });
In both the event for the markers and the click
event of the map, we are using the fadeIn
and fadeOut
methods of jQuery to animate our external maps visibility.
When you try to drag around the higher-level map (the first visible map), you will notice that the map cannot move—it's not pannable. Google API v3 doesn't support the capability to disable the panning, but it does support the capability to get updated every time the map center point changes.
As such we listen in to the following change:
google.maps.event.addListener(mapOut, 'center_changed', function() { mapOut.panTo(BASE_CENTER); });
All we are doing is that each time the map position changes, we force it back to its original position, making it impossible to move our map around.
3.139.86.56