Startup Weekend Houston

This past weekend I participated in Startup Weekend Houston. For some reason I ended up in the UI design group, even though my specialty is front-end web-dev. I had a blast though, working with the UI team, Matt Alberty, Marcus Mateus, and Ramesh Bhaskar. Two and a half days went by incredibly fast, and in the end we ran short on time and only partially launched. But, this project will keep moving forward. We created TipDish, a news wire for social media. If you blog/dish, you can register at the site to receive tips pertinent to the subject(s) you blog about. We expect a full launch sometime this month.

The Tooltip Gets a Shadow (and DOM Node Support)

In the spirit of consistency, I decided to add a shadow to the tooltips (View the example). They just didn't blend in with the rest of the Google Maps overlays. So I set out to replicate the "standard" Google Maps shadows.

Replicating the Shadow

Through a mix of reasoning, instinctive guessing, and trial and error, I have devised a technique to replicate the shadows using Adobe Photoshop. It's a fairly simple process and the steps are outlined below.

  1. Make a copy of the overlay's layers and merge and rasterize the copies if needed
  2. Make the copy all black (I use a gradient map and set both ends to black)
  3. Perform a Free Transform and set the Height/Vertical Scale to 50% and the Horizontal Skew to -45° Photoshop Free Transform Settings
  4. Apply the Gaussian Blur filter (I set it to .5 pixels for small images and 2 to 3 pixels for large ones)
  5. Set the Opacity to 45%
  6. Save the shadow layer only as a PNG

Drawing the Shadows on the Map

After figuring out how to replicate the shadow, I moved on to drawing it on the map. The first step to drawing the shadow is getting its size and location. From replicating the shadow we know that the height is 50% (plus padding for the Gaussian blur). The width of the shadow is the width of the tooltip, plus half the height of the tooltip (and again, the padding). Half the height of the tooltip is added to take into account the offset of the shadow's top, right corner caused by the skew. Since the skew is 45 degrees, the offset is a one to one ratio with the height of the shadow. The position of the tooltip's shadow is relative to the marker's shadow. So I apply the same principles to the marker's dimensions in order to calculate the position of the tooltip's shadow.

tooltip shadow quadrants

Because the size of the tooltip is not fixed, the shadow needs to be able to grow vertically and horizontally. I accomplish this by dividing the shadow into four quadrants. Each quadrant contains the same shadow image, positioned to display its respective corner. The image's positions in the first and third quadrants are straight forward. The image is positioned so the top and right edges of the image line up with the top and right edges of the first quadrant. The bottom and left edges of the image line up with the bottom and left edges of the third quadrant. The positioning of the image in the second and fourth quadrants requires some simple calculations. The image in the second quadrant is placed so the top edge of the image lines up with the top edge of the quadrant. The left edge of the image is offset from the quadrant's left edge. The image in the fourth quadrant is symmetrically opposite from the second, bottom edge of image to bottom edge of quadrant and right edge of image offset from the right edge of quadrant. See the source code, the Tooltip.prototype.redraw method, for the calculations of the offset.

The code below is a sample of the xhtml generated by the Tooltip object to create the shaow. The parent div is the container for the entire shadow, it is outlined in black in the image above. The child divs represent the quadrants of the shadow. Each quadrant contains a reference to the same shadow image and the image is positioned relatively to the quadrant.

<div style="position: absolute; visibility: visible; left: 300px; top: 197px; width: 226px; height: 32px;"> <div style="overflow: hidden; position: absolute; right: 0px; top: 0px; width: 113px; height: 16px;"> <img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; top: 0px; right: 0px;"/> </div> <div style="overflow: hidden; position: absolute; left: 0px; top: 0px; width: 113px; height: 16px;"> <img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; top: 0px; left: -128px;"/> </div> <div style="overflow: hidden; position: absolute; left: 0px; bottom: 0px; width: 113px; height: 16px;"> <img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; bottom: 0px; left: 0px;"/> </div> <div style="overflow: hidden; position: absolute; right: 0px; bottom: 0px; width: 113px; height: 16px;"> <img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; bottom: 0px; right: -128px;"/> </div> </div>

Better visited links?

I was recently checking my site traffic reports to see where my visitors were coming from and I found a mind-blowing (at least for me) CSS technique for visited links. Eve-Lotta Lam uses a check mark background image for visited links rather than simply changing the text color. You might not think that this is mind-blowing, but consider that using background images to attach information to links has been around for awhile now, i.e. external link icons.

Why has this technique not been applied broadly to visited links as well? It makes so much more sense than changing the color. You don't have to think about which color corresponds to a visited link as opposed to a non-visited link. The color swapping doesn't really help across different websites because there is no standard convention for which colors to use. The exception may be blue for non-visited purple for visited, but these are antiquated and clash with most websites' color schemes. Using a check mark doesn't require that users remember a link had a different color when or if they re-encounter it after they have visited the it the first time. Users do not have to compare one link's color to another and try to remember which of those links has been visited and which has not. The check mark conveys the same meaning without requiring the user to think as much; it is a much better solution.

Evalotta pointed out that Paul Boag also uses this technique. If you know of any others, let me know.

Geocoding with the Google Maps API

tooltip sample

I've been working more and more with the Google Maps API recently. And one thing strikes me as odd; it's difficult to find examples of how to retrieve geocodes for addresses. If you're going to implement the API in a website, you usually have to take multiple addresses and convert them to geocodes. But how do you do this?

Enter Geocoder. You may be asking yourself, "Who's Geocoder?" No, no my friend; Geocoder is not a who, it's a what. It is a little webapp that will retrieve the coordinates of any address (known to Google Maps), using the Google Maps API. The beautiful thing about Geocoder is that it allows you to perform batch retrievals using any character(s) to separate the records. Geocoder also gives you the ability to drop a draggable marker onto the map and it will tell you the coordinates of the location you move it to. This is extremely helpful for locations without addresses. And best of all, Geocoder is completely free and onemarco.com-independent. "How," you ask? Simple, you can download Geocoder and insert your Google Maps API key in the index file. It will run on any web server as long as you have an API key. I've even zipped it up into a convenient archive so that you can download all the files with one click.

Geocoder is free to use for any reason without any restrictions. Just credit me if you redistribute it.

View Geocoder in action.
Download Geocoder.zip.

P.S. I would like to thank Simon Reynolds for designing my masthead. You can check out his blog at SR28.com and his artwork at 4StoryStudio.com. His blog is designed beautifully.

Custom Tooltips for Google Maps

Welcome to my JavaScript blog, onemarco.com, or as I like to call it, Blog de Alionso. I’ve been developing with JavaScript for about six months now and I’ve learned so much from others’ blogs. I'll be sharing some of the scripts I've developed recently, in the hopes that my experience and knowledge will help others.

tooltip sample

What?

Today I present the Tooltip object for Google Maps. It is used to add quickly-appearing, easy-to-style (via CSS) tooltips to Google Maps' markers. This is in contrast to the built-in tooltips of versions 2.5 and higher, which appear after a short delay and cannot be styled. You can view an example the new example of the tooltips in action which also includes a sidebar.

View the Tooltip source code. The code is free to use for any reason without any restrictions. Just credit me if you redistribute it.

Why?

I developed the tooltips for two reasons. First, I find it difficult to figure out which marker a sidebar entry belongs to. It is time consuming to look at the letter for the entry and find the matching letter on the map, especially when markers overlap and hide each other. It is easier if the tooltip appears above the marker when I hover over the sidebar entry. Secondly, sometimes I just want to quickly figure out what a certain marker on the map is without having to look for its corresponding letter in the sidebar. And having to click on the marker to pull up the location's name is annoying, especially when it moves the center of the map. It just seems natural to me that when you hover on a marker, the name of the location should appear. Besides, it was a good exercise in extending the Google Maps API.

How?

Adding tooltips to a Google Map, using the Tooltip object is easy. I'll explain the steps I use when implementing the tooltips. The constructor for the tooltip takes three parameters: the marker, the text, and the padding between the tooltip and the marker.

var marker = new GMarker(new GLatLng(29.78933,-95.716748)); var tooltip = new Tooltip(marker,'HEB Grocery Store',4); marker.tooltip = tooltip; map.addOverlay(marker); map.addOverlay(tooltip); GEvent.addListener(marker,'mouseover',function(){ this.tooltip.show(); }); GEvent.addListener(marker,'mouseout',function(){ this.tooltip.hide(); });

After I've created the tooltip, I set it to the marker's tooltip property. Then, I add the marker and tooltip to the map via the addOverlay method of the GMap2 object. The last step is to add the mouseover and mouseout listeners to the marker to show and hide the tooltip.

Things to consider

  • You may want to suppress the tooltip when the GInfoWindow is open. Since the markers do not have a property that indicates whether their info window is open, you would need to add listeners to their infowindowopen and infowindowclose events. For an example of how to do this check out the source code of the Tooltips with drop shadows example.
  • Another possible extension would be to add a timeout to the hide method of the Tooltip object to delay how quickly the tooltip disappears.
  • One limitation of the tooltip is that it currently only supports text. If you wanted more advanced styling, you could add support to the Tooltip object for inserting DOM Elements. The new version of the tooltip now supports DOM Elements for the content.
  • The Tooltip object does not cast a drop shadow. If you want to keep it consistent with the Google Maps look-and-feel, this would be something to consider adding. The new version of the tooltip now casts a drop shadow.