SVG
Page 12
Interactive USA Map: Introduction
Learn to apply Adobe Illustrator, JavaScript and HTML5 to create an interactive map of the USA with SVG. This map scales easily based on device and screen size.
Illustrator
I downloaded a public domain map of the USA, created paths and polygons on separate layers. Each layer's name reflects the state the path outlines.
When saved as an SVG text file, each state represents an element and the layer name is an ID.
Tap a State
SVG JavaScript Click Events
You can add JavaScript events within Adobe Illustrator. However I chose to access SVG elements by ID, then add click events later.
Illustrator Click Events
Within Adobe Illustrator's layers panel, select the circle toward the right of an Illustrator element. Right click and the circle highlights. Go to Window > SVG Interactivity. Enter a click event and browse to your JavaScript file.
SVG Markup
Paths, rather then
group elements, in SVG caused a few problems.
For example <path id="VA" d="...z" />
caused some problems when more than one path ID follows
another path ID.
Solution
I surrounded the path with a group element,
<g>...</g>
.
I ended such paths with a digit, rather than z
.
Paths that end with z
represent
Close Path
.
For example the path for Montana caused some problems until I surrounded the path with a group. The following abbreviation demonstrates correcting the issue.
<g id="MT"> <path fill="#2AA5DE" d="M187.988,...73.042" /> </g>
See the SVG file, United States of America.
HTML5
Display the SVG within an object tag. This allows JavaScript to access SVG group and path IDs.
The JavaScript onload
event,
onload="svgDocLoaded(event)"
,
allows code to access SVG group, path
and polygon IDs.
<object id='svgUSA' class='w100' type='image/svg+xml' data='assets/states_all.svg' onload="svgDocLoaded(event)" > </object>
HTML Script Tag
Normally JavaScript files load asynchronously. However at times a race condition existed.
Before
The SVG might load before
JavaScript code loads.
Therefore a JavaScript onload
event won't trigger.
After
The SVG element might load after JavaScript loads. Therefore JavaScript initialization code can't access SVG IDs.
Verify JavaScript Loads First
This example requires JavaScript to load before the SVG loads.
The keyword async
before most JavaScript files,
allows JavaScript to download
based on Internet connectivity speeds.
Developers don't know if code
will download before or after images.
To ensure JavaScript downloads
with the Web page,
omit async
from the following typical JavaScript link.
<script async src="javascript/map-usa.js" >
Load JavaScript Synchronously
Load JavaScript file map-usa.js
,
as follows.
<script src="javascript/map-usa.js" >
Audio Tag
Include an audio tag to chime when the user taps a state.
<audio id="aRight"> <source src="https://7thunders.biz/audio/effects/chime.mp3" type="audio/mpeg" /> <source src="https://7thunders.biz/audio/effects/chime.ogg" type="audio/ogg" /> </audio>
JavaScript
The following JavaScript accesses SVG element states by ID, creates two properties on each state and assigns the same click event handler to each state.
Each state element receives a property
with the state's name.
The property's a string called
sName
.
Each state element receives a property
with an HTML element.
The property's named eDebug
.
The click event handler displays
the state's name to the HTML element
on the Web page.
Upload to Server
To access SVG content, either maintain a local server on your PC or upload SVG objects to a Web server.
Save Memory
Instead of a constant array of
states
you could conserve memory with
an array that's local to
method getStateIDs()
.
When method getStateIDs()
completes, then the Web browser
can free the array of State
objects.
JavaScript for USA Project
The following JavaScript file originally provided interactivity for this project, and worked fine. Later I decided to share JavaScript files, across subdomains, for more compact, easier to maintain code.
You may download map-usa.js.
First declare an object named
State
with two string
properties named sID
and sName
.
/** * State Object * @param sId: String named identifier. * @param sName: string state name. */ var State = function(sId,sName){ this.sId = sId; this.sName = sName; } // Array of State // objects. var aStates = [ new State("WY","Wyoming"), new State("RI","Rhode Island"), new State("CT","Connecticut"), new State("NJ","New Jersey"), new State("DE","Delaware"), new State("MD","Maryland"), new State("WV","West Virginia"), new State("VA","Virginia"), new State("NC","North Carolina"), new State("SC","South Carolina"), new State("GA","Georgia"), new State("AL","Alabama"), new State("MS","Mississippi"), new State("LA","Louisianna"), new State("AR","Arkansas"), new State("TN","Tennessee"), new State("KY","Kentucky"), new State("OH","Ohio"), new State("IN","Indiana"), new State("IL","Illinois"), new State("MO","Missouri"), new State("FL","Florida"), new State("TX","Texas"), new State("NM","New Mexico"), new State("AZ","Arizona"), new State("UT","Utah"), new State("NV","Nevada"), new State("CO","Colorado"), new State("NE","Nebraska"), new State("KS","Kansas"), new State("OK","Oklahoma"), new State("IA","Iowa"), new State("SD","South Dakota"), new State("ME","Maine"), new State("NH","New Hampshire"), new State("VT","Vermont"), new State("MA","Massachusetts"), new State("NY","New York"), new State("PA","Pennsylvania"), new State("CA","California"), new State("OR","Oregon"), new State("WA","Washington"), new State("ID","Idaho"), new State("MT","Montana"), new State("MD","Maryland"), new State("MN","Minnesota"), new State("WI","Wisconsin"), new State("MI1","Michigan"), new State("MI2","Michigan"), new State("AK","Alaska"), new State("HI","Hawaii") ]; // HTML elements var eDebug = null; var svgDoc = null; var svgUSA = null; // Audio elements var aRight = null; // Number of States. var nStates = null; /** * Obtain elements * needed by JavaScript. * @returns SVG content * or null */ function getElements(){ eDebug = document.getElementById( "eDebug" ); // Audio elements aRight = document.getElementById( "aRight" ); // Length of array. nStates = aStates.length; // svg with USA map. svgUSA = document.getElementById( "svgUSA" ); // Get SVG document // inside the Object tag svgDoc = svgUSA.contentDocument; // If problems accessing // SVG contents // this will be null. return svgDoc; } /** * Onload event for * SVG image. * @param event: Event Object. */ function svgDocLoaded(event){ svgUSA = event.currentTarget; let valid = getElements(); if(valid == null){ eDebug.innerHTML = "svgDoc is null."; } else{ getStateIDs(); } } /** * Get state elemtents * by ID. * Assign click event * listeners to * each state. */ function getStateIDs(){ try{ for (i = 0; i < nStates; i++){ // State object let oState = aStates[i]; // State elemtent let eState = svgDoc.getElementById( oState.sId ); // Save properties eState.eDebug = eDebug; eState.sName = oState.sName; // Click event listener. eState.addEventListener( "click", tapState, false ); } } catch(ex){ eDebug.innerHTML = ex.toString(); } } /** * Respond to click * events. * Display state name. * @param ev */ function tapState(ev){ let state = ev.currentTarget; let eDebug = state.eDebug; let sName = state.sName; eDebug.innerHTML = "You tapped "+sName+"."; aRight.play(); }
See the Code
The following JavaScript file, map-usa.js includes code presented here, with a few more audio elements.
Possibilities
Developers can easily display information specific to each state such as the state's history or current election results.
Consider pulling state information from a database for display when the user taps a state. Databases allow easy modification of data.
Summary
You learned to apply Adobe Illustrator, JavaScript and HTML5 to create an interactive map of the USA with SVG. This map scales easily based on device and screen size.
SVG Illustration
Create a range of Scaleable Vector Graphics (SVG) with Adobe Illustrator, HTML or plain text files. The SVG format proves ideal for lightweight, clean, crisp images that never lose their luster.
SVG images export as text files allowing designers and artists to modify properties, within the file, such as fill, background color, gradients and scaling.
Apply JavaScript and CSS3 to modify properties interactively or automatically. Animate, or respond to user interaction, to change a range of properties including color, opacity, location, scale, gradation and more.