Thursday, July 26, 2012

More Google I/O take away

Some years ago, a well-known CEO stood on a stage and screamed that his company and the future was all about "Developers! Developers! Developers!" Since then, the sheer diversity of platforms has exploded, the web continues to advance in content and functionality, and the world supply of developers has grown with mixed result.

As a developer who takes pride in building advanced web applications, I have seen on more than one occasion the negative side of the focus on and proliferation of so-called "developers": trash code that is more often than not brittle, insecure, and clunky. To the average end user, this means that, despite all of the advances in processor, RAM, HDD/SSD, and network technologies, they continue to wait on the applications that they use on a daily basis.

Enter Google I/O. This year, perhaps more than ever, the recurring and overarching theme of the conference was performance. From Project Butter in Android 4.1 to a heavy emphasis on debugging and performance analysis in the WebKit Developer Tools, speed was the talk of the conference. And rightfully so.

Some of the tricks that I picked up at I/O for improving performance in my web apps are briefly described below. I would love to hear what you use to trick the most speed from your apps and/or your experience with one or more of these tools.

Closure

The compiler. Not necessarily the library. Closure, when advanced optimizations are enabled, is a powerful tool for automagically reducing the size of your JavaScript and optimizing those sections of your code that could run faster. I've been using Closure Compiler for more than a year now, and it's simply awesome.

WebKit Developer Tools

With outstanding debugging and in-browser CSS, Javascript, and HTML editing, WebKit's Developer Tools were already pretty awesome. But Google and the WebKit team have continued to push in this area over the last year to make it even more impressive. When it comes to performance, the Timeline feature alone is worth its weight in gold. (Okay, so it doesn't "weigh" that much, technically. But it is still awesome!) Essentially, this feature helps you find exactly what, when, and where, your application is running into a bottleneck. And it helps you make sure that your users will never see the "jank" that so often characterizes web applications.

Accessibility

Okay, so this doesn't really have to do with performance. But if someone can't use your application because they are visually or otherwise impaired, performance is a moot point anyway. Fortunately, the Chrome team has been working on a number of tools for helping developers improve the accessibility of their websites and applications. Tools such as High Contrast, ChromeVOX, and Accessibility Developer Tools go a long way toward making accessibility accessible for developers.

Server-side performance optimization

Too often, particularly with web applications, the real bottleneck is not on the browser. It's not even in the network. It's where the application relies on the server to do something. Make sure that your server-side stuff is optimized. Simple things such as setting expires headers, enabling gzip compression, etc., go a long, long way.

CSS optimization

Some CSS rules bring the browser to a crawl while others can achieve virtually the same effect and still scream. Particularly with CSS3 transform3d and more, you can offload a pile of stuff to the GPU and radically improve performance.

Smart JS

The V8 JavaScript engine is pretty smart. And the other JS engines out there (e.g., Safari, Mozilla) are not far behind. But understanding just how smart they are - and how that smart works - is essential. One very quick example is in the case of prototyped objects. If objects use the same prototype, they will be given the same hidden class in the JS engine. This means that they will share a bunch of optimized code behind the scenes, thus speeding up everything they do. But the instant that you add one custom property to one of those objects, you break it out of that shared, optimized code. Surely, you could hear the screeching sound of your application grinding to an abrupt halt. Do everything in your power to avoid giving objects which are otherwise identical to a thousand others on the page some custom property.

Jelly Bean

Android 4.1 (aka, Jelly Bean) includes a plethora of tweaks to the ICS UI and UX which basically make life faster, smoother, and better. And while this probably isn't a developer tip, I am going to throw it out there. You want Jelly Bean. Not tomorrow. Or next week. But now. And sadly - or maddeningly, I think, from Google's perspective - OEMs and carriers are going to drag their feet in deploying it, and when they finally do push it out the door, they'll figure out how to bog it down with some hack-job custom UI and a pile of bloatware. Demand a vanilla Jelly Bean device from your carrier sooner, rather than later. Tell them that you would even pay extra for the thing so they didn't cripple it with bloatware and custom (read that, junk) UIs.

So there you have it. Just a few of the more technical takeaways that I brought home from Google I/O. Of course, this is a very quick hit list. And in order to actually utilize these tips, you'll have to do more research on your own. I would suggest that you start by going to YouTube and searching for related sessions from I/O 2012.

Monday, July 9, 2012

To I/O and beyond...

In the movie Toy Story, Buzz Lightyear has a particular tagline: "To infinity and beyond!" It embodies the space ranger's sense of adventure and courage, and challenges the hearer's imagination to suspend reality and, for at least a moment, embrace the limitless possibilities of life and the future. In more ways than one, Google's annual developers conference, I/O 2012, was an exercise in exactly the same.

June 27-30, I was privileged to be one of the approximately 6,000 people to attend Google I/O 2012. This was my fourth I/O - I've been to all of them but the inaugural event in 2008 - but in many ways, this one was dramatically different than all the rest.

For starters, it was bigger. Of course, there were more people. And the conference was a day longer. But what I really mean is that Google pulled out all the stops to make this I/O a phenomenon. During the Day 1 Keynote, for example, they demonstrated Project Glass in spectacular fashion with a live parachute drop, stunt bikes, and rappelling. Then, at its conclusion, the Android team announced the single largest giveaway in I/O history (which is, for the record, saying something). Add to this a second giveaway during the Day 2 Keynote and more sessions than ever before (they did add a day, after all!), and you have the makings of something huge!

But I/O was also about a message. Going into the conference, I was hearing a lot of rumblings about how people were confused about Google's direction of late. We all knew that the company is committed to Android and the open web, but with rumors swirling of Facebook and numerous others poaching Googlers, the plethora of disparate projects that Google has been supporting for years, their rather questionable progress in the social arena (read that, Google+), the firestorm still raging about their commitment (or lack thereof) to privacy, and more, there were serious questions in the air. Throughout the conference, I truly believe that one of Google's primary purposes was to communicate that the company, its products, and (perhaps most importantly) its culture are alive and well.

So, what did I take away from I/O 2012? I think there were three things.

First, I learned a lot, particularly about performance. There was a pile of sessions dealing with Javascript performance, developer tools, and basic (and not-so-basic) tips for tricking the most speed possible from a website in general or a particular web application.

Second, Google is frustrated with the state of Android. Namely, they are frustrated that they continue to pour time, energy, and resources into developing an excellent mobile platform while OEMs and carriers squander it all with second-rate hardware, sad skins and bloatware, and an utter lack of commitment to upgrades. I can come up with no other explanation as to why they would hand out a Galaxy Nexus phone - the only phone to run a vanilla Android build and get OTA updates directly from Google - and enter the tablet market themselves with the Nexus 7. In particular, I think the Nexus 7 is a shot across the bow of Amazon (because the Kindle Fire, best-selling Android tablet by far, is still running Android 2.3) and Samsung (whose flagship Galaxy Tab 10.1 - i.e., the tablet Google handed out last year - is plagued with quality issues and still running Honeycomb rather than Ice Cream Sandwich). I think Google is recognizing that the fragmentation of the Android ecosystem will eventually - probably sooner than later - make the entire platform untenable, or at least undesirable. And they're hoping that, by spurring developers and the world with a taste of Jelly Bean goodness on good hardware will prompt their partners to get their heads in the game and their acts together.

And the third thing I took from I/O is that Google isn't quite sure about how to find the balance between pleasing shareholders and maintaining the creativity and culture that has made it Google since day one. So on the one hand, we have Google doubling-down on Google+ (which investors rightly believe is key to the search giant remaining viable and growing in the advertising space) and monetizing APIs and services such as the Custom Search and Translate APIs (which investors are understandably loathe to simply give away to anyone and everyone). And on the other hand, we have a company which produces products as blatantly whimsical as the Nexus Q and as boldly next-generation as Project Glass (which, to be honest, I think should be called VISOR in honor of the device worn by Geordi LaForge of Star Trek: The Next Generation). They continue such endeavors as GoogleTV while simultaneously introducing the Nexus Q, which essentially reproduces a significant chunk of GoogleTV's features. To be honest, it seems as though they're on a seesaw, using a scattergun, blindfolded, trying to hit a moving target.

Given these take-aways, what am I looking for down the road?

Well, on the web side of things, I anticipate that Google will continue to use Chrome to push the state-of-the-browser and advance the open web. The company is fully invested in HTML5 and actively working to push it even farther. I also see that performance is going to become even more critical because it affects not only user experience but also the bottom line. I see that mobile is going to continue to grow, and with it, there will be an ever-widening range of form factors (read that, display sizes) to consider when building a website or app. And I see that Google will continue to push so that, even given the wide range of form factors, there will be an unprecedented continuity of capability and user experience across all of these devices.

On the Android side of things, while the pair of Nexus devices in the giveaway on Day 1 was not exactly the opening salvo in a war on OEMs and carriers, it was certainly another warning shot. Google is growing impatient - and it's about time! - with the hardware manufacturers and carriers who are perpetually gimping what has become a mature and powerful smartphone platform. These partners need to look at the iOS ecosystem and realize that fragmentation is a bad thing (iPhone 3 can still run the latest iOS software with only a few caveats!) and their crumby customizations are hurting everyone in the realm. Build hardware that's not crippled. Don't shoot the OS in the foot on the way out the door. If you're going to build Android products, build Android products!

And on the corporate side of things, I hope we'll see Google figure out who they are and where they're going, and then be that company and go that way. Get over trying to impress the shareholders. If they're not impressed with your results to date, then they're probably insatiable. You're making money. Lots of money. Now, get back to making the world - particularly, the internet - a better place.

Tuesday, June 26, 2012

Dynamic, asynchronous websites made simple with JSONP

I remember the first time I discovered the potential of XMLHttpRequest. It was mind-boggling. I was in heaven with all the stuff I could do. I played like a kid in a candy store until, suddenly, cruelly, I ran headlong into two major problems with XMLHttpRequest:

  1. You couldn't get info from anything but the originating server
  2. XML stinks.

And then one day, I stumbled upon JSONP. I still remember the day. I had been working with the Google AJAX APIs, and I wanted to know how they got around the two inherent limitations in what I understood to be AJAX. So I dug into their obfuscated code and watched their network traffic for hints. And there it was: they didn't use XMLHttpRequest or XML.

Instead, they used a method called JSONP. (They just called it AJAX because that was the major buzz word at the time.)

JSONP is really a very simple, elegant, and flexible way to communicate dynamic data between client and server. And it's fast. Because it uses JSON rather than XML, the data transfers are smaller and the time it takes for the Javascript engine to parse the data is dramatically shorter. So in comparison to traditional "AJAX," JSONP screams.

Why is it, then, that most people haven't heard of JSONP? And why is it that, whenever I suggest it to people, they stare at me with this blank expression on their face as though I was speaking in some alien language?

Well, the only reason I can come up with is that "AJAX" is the buzzword. It just sounds a whole lot more cool (and clean) than JSONP. And so, since most people have heard only of AJAX, it actually is as though I'm speaking in some alien language when I suggest JSONP.

So let's fix both of these problems in one shot. From here on out, we'll call JSONP the "Super Spiffy Way To Communicate Data Between Your Client And Your Server" (SSWTCDBYCAYS).

Okay, let's not do that.

Seriously, though. Let's see if we can't figure out this mysterious thing called JSONP quickly and easily, once and for all.

In any dynamic web application, there are two sides of the equation: client and server. The client side is what's going on in the user's web browser. The server side is what's going on in - you guessed it - my web server. For the sake of this discussion, we're going to start on the client side, with the Javascript, since that's where the bulk of the hocus-pocus happens.

On the client side, everyone knows that an HTML page is comprised of a series of elements formed into some semblance of a hierarchical structure. (It doesn't matter if you don't get that. Just pretend and keep reading.) Some of these elements can instruct the browser to fetch additional resources from the server. For instance, <img> tags tell the browser to ask the server for an image file; <link> tags can ask the server for a CSS stylesheet, and <script> tags can order the browser to fetch a Javascript file. That last one right there is the key to JSONP.

You see, the secret to the black magic of JSONP is that you can use Javascript to dynamically construct additional <script> elements to append to your page. And the browser will obediently go and fetch those scripts from the server whenever you do.

So all we have to do is write a little Javascript function that uses DOM methods to build and append a new script element to the page. Something like this:

function do_json(url){
  var el = document.createElement('script');
  el.src = url;
  el.type = 'text/javascript'; // gotta be PC here!
  document.getElementsByTagName('head')[0].appendChild(el);
}

Now, any time you want to fetch information from the server, all you have to do is call do_json(<url_of_the_js_file_i_want>); .

Of course, that doesn't help us a whole lot if the server returns a blank stare. So for the next step, we have to turn to the server, where we write a script or program that will get data from any source you can dream up (e.g., database, XML, thin air, subspace transmission from Starfleet Command) and return it in a JSON format.

JSON, by the way, stands for JavaScript Object Notation. It's essentially a string which represents a Javascript object. Something like this:

{
  "name" : "Jeremy",
  "rank" : "Generally Cool Guy",
  "serialNo" : "1234567890"
}

That is a very simple JSON string representing an object with three properties: name, rank, and serialNo. So the bulk of this step in the JSONP process is getting my server to return data in that sort of format. Of course, exactly how you will do that will depend on your backend and language of choice. So I will let you Google how you might do that.

Once you figure out how to get your server to return JSON, we still have a problem. Simply returning JSON to the browser is like taking a phone message without writing down who it's for. Now, you could set the message on the corner of your desk in the hopes that the right person will happen by, notice it there, and grab it. But the chances of that happening are pretty slim. So our server has to be a little more specific. Namely, it has to encapsulate the JSON string in a Javascript call. So instead of the string we had above, we end up with something like this:

my_callback({
  "name" : "Jeremy",
  "rank" : "Generally Cool Guy",
  "serialNo" : "1234567890"
})

Now, that should look familiar. It's plain Javascript. You're calling the function my_callback and passing it the Javascript object you created above. Simple enough.

The problem now is that my_callback isn't home on the client-side just yet. So let's add it to the client-side Javascript code that we had before.

function my_callback(response){
  // do something!
}

All of a sudden, my_callback is eagerly awaiting its message, and as soon as it gets it, it can take off running.

Now, this is just the tip of the iceberg. Because the actual body of the server's response could be an array, an object, a number of arrays or objects, or any number of other things. And you could use it to rewrite your page, update particular elements, and much, much more. The sky is the limit! And because you're not using the SOP-restricted XMLHttpRequest, you can request data from any server on the web, making it possible to create services on one server which can be utilized from any number of sites. And it's a whole lot faster, to boot!

Once you grasp the concept of JSONP, your mind will just start seeing possibilities for uses. Search engines. Maps applications. Updating content. The list is virtually endless.

Well, folks. That's all the time we have for today. We hope you've enjoyed the broadcast! Please tune in next time as Jeremy writes about taming your very own water buffalo!

Thursday, June 14, 2012

Google I/O 2012 expectations

So, I happen to be one of the lucky 5,500-ish people who has a ticket to Google I/O 2012. That is, if the confirmation email I received is to be believed. This will mark the fourth time I've trekked to San Francisco and the Moscone Center for what has become one of the most anticipated technology events of the year. (In fact, you could probably make an argument that it is the most anticipated tech event, but I will leave you to decide how it ranks with CES and WWDC, etc.) But this year is different in a number of ways for me.

In the past, while I have always looked forward to the tech stuff, I/O has been an annual opportunity to meet friends from around the globe that I never see otherwise. This year, however, none of my friends are making the trek for I/O.

Also in the past, I have scheduled flights to and from SFO so that I would be there and back as quickly as possible (i.e., I arrive late afternoon/evening the day before and depart early morning the day after). However, this year, the airlines have left me with what is going to amount to a half day of nothing on either end of the trip. So I may actually have a chance to get out to see a couple of sights.

I suppose, though, that all of that is a moot point. And it's probably not why you're reading this post. With less than two weeks to go before the opening keynote of I/O 2012, you're looking for what I'm expecting to see and hear coming out of the Great Big G. So here are some thoughts that I've been contemplating.

  • Android. It is a foregone conclusion that Google will use I/O, as it has each of the last three years, to preview the next iteration of the Android operating system. I expect we'll hear some astounding activation numbers and see some awesome developers spotlighted. But what I am really looking for is some sort of plan to stop Android fragmentation. Clearly, with any open platform, there is going to be fragmentation as companies try to distinguish their products, but when I bought a Samsung Galaxy S phone from my cell carrier 2 years ago, I expected that it would be stable and receive updates in a timely manner. To the contrary, while the phone is stable most of the time, I am still compelled to remove the battery every few days because it's frozen or going berzerk. The Froyo update, which was released nearly 9 months after the fact, was such a disaster that I skipped it altogether. And the Gingerbread update, while fixing some bugs, came only after Ice Cream Sandwich was already in the wind and included issues of its own. And then there was the fact that I had to use Samsung's Kies software to install the updates. Kies, however, does not run on my Mac. And I was never able to get it to perform the updates on a PC. So I want to see a mandate that Android phones will receive automatic OTA updates of at least the base platform in a timely manner.
  • HTML5. With the introduction of MSIE9, HTML5 became a viable option for a wide variety of things. I am looking for Google and others to provide insight into what browsers will be doing to push the envelope over the next year. I'm particularly interested to hear about advanced filters in CSS3 and such.
  • Chrome OS. I have been a fan of Chrome OS since it was first officially announced. I have a CR-48 that I use frequently. I had a Samsung Series 5 Chromebook, but I gave it to someone who needed it. The lightweight platform has very real potential for those who live, primarily, in the cloud. However, adoption has been somewhat lackluster. I am therefore concerned that the big G will grow weary of maintaining two complete operating systems (i.e., Android and Chrome OS). So I will be listening for a sense of direction on that front. I hope that Chrome OS does not go the way of Wave and Buzz and such.
  • Performance. Over the last couple of years, I have been spending increasing amounts of time working to optimize my web applications and sites for performance. It's like a challenge to trick out every bit of speed I can. (Some people do this with lawnmowers or cars; I do it with web stuff). So I'm looking to learn a lot about what the Chrome team and others are doing to ramp performance in the browser.
  • Brainfreeze. I hope to learn so much that my brain seizes sometime during day 3 of I/O. That's right, they added an extra day!

So, that's about it for my expectations. I would love to hear what others are anticipating at I/O!

Monday, June 4, 2012

What I learned about the canvas element

So, I am apparently a sucker for challenges. A couple of weeks ago, my friends at the Des Moines Web Geeks issued the challenge to re-build in Javascript a simple dungeon game, which one of the organizers had built with his son in Python. I was unable to be at the coding dojo itself, but I joined in via Google Hangouts. And for some reason, I was hooked on the challenge.

But it was more than just the notion of rebuilding this simple game. The idea behind the whole thing was to teach someone how to code, a prospect which I have long thought to be a distinct challenge for our times. And we were supposed to use OOP JS as much as possible, something which I really enjoy. And then there was the fact that, beyond the basic parameters of the game, the concept was left wide open, which immediately got my imagination going.

So I decided from the very start that this little game, for me, would have two primary objectives:

  • I would learn something
  • Someone else would be able to learn something

For the thing that I would learn, I decided I would explore canvas to build a dashboard of sorts to display at a glance the status of the current player, the monster in the room, and a map of the world. Namely, since I had never before utilized the HTML5 canvas element in any project, I wanted to learn some of the basics and then explore just what the thing could do. I was incredibly pleased with what I came up with, and I wanted to share just a couple of quick lessons that I learned in the process.

The first lesson has to do with the canvas element itself. When I first started using canvas, I was simply putting the basic element into my HTML and then setting width and height with CSS. At first, things looked great. But as soon as I started drawing in the canvas, I realized that something was messed up. The images were distorted somehow. For example, a 5px vertical stroke was thicker than a 5px horizontal stroke. And then I noticed that filled rectangles that should have filled the entire canvas were all messed up. And I was compelled to realize that, somehow, there was a discrepancy between the internal dimensions of the canvas (i.e., how many pixels it thought it had) and the external dimensions of the canvas (i.e., how many pixels the page thought it had).

Sadly, it took me quite some time to find a tutorial or other documentation which acknowledged what I thought must have been an issue. But it wasn't an issue. Rather, it was a design feature of the canvas element.

<sarcasm>Imagine my surprise.</sarcasm>

So here's the deal. The canvas element's height and width attributes (i.e., the height="xxx" width="yyy" bits you put in the HTML) set the dimensions of the drawing space within the canvas element. While the CSS height and width rules set the dimensions of the element in relation to the rest of the page. The thing is, those two things don't necessarily correspond.

In fact, the canvas element, regardless of its size in the CSS, will have a drawing space of 300 pixels wide and 150 pixels in height. Unless, that is, you specify otherwise. The question is, how do you do that? Well, there are two options.

The first option is to specify it in the markup. Namely, by providing the height and width attributes in the opening tag, like this:

<canvas id="myCanvas" width="1000" height="1000" />

That's not so difficult. But what if you want the canvas drawing space to be exactly the same as the canvas element's actual dimensions on the page? And what if the actual dimensions are given in a percentage or may change? Try something like this in your JS onload callback (or onresize, etc.):

var el = document.getElementById('myCanvas');
el.setAttribute('width', el.offsetWidth);
el.setAttribute('height', el.offsetHeight);

And there you have it. One of the things I learned about canvas elements while playing with this simple little game.

i love my wife

Tuesday, November 15, 2011

Adventures in browser detection

So, today, I came across an interesting issue. I am working on a total overhaul of my personal CMS, and part of that includes a custom WYSIWYG editor. The editing happens inside an iframe element, but in order to make it a seamless experience, I want the iframe to dynamically resize itself according to whatever the contents need for dimensions. Makes sense, right? Well, then I come across this little beauty:

In order for it to work right, I have to use the dimensions of the iframe's body element in Chrome. But I have to use the dimensions of the iframe's html element in Firefox. Talk about irritating. So now I have to distinguish between these two great browsers. I think to myself, "Oh, well, that shouldn't be too difficult." And I tried using navigator.product. No joy.

Turns out, Chrome sets navigator.product to Gecko, just like Firefox. Even though Chrome is NOT Gecko.

So I thought maybe appName. Chrome sets its navigator.appName to... "Netscape".

appCodeName? Chrome sets it to - you guessed it - "Mozilla".

So I was compelled to check the userAgent string. But because Chrome and many other browsers report their UA strings as "Mozilla/5.0..." I knew Mozilla was out. I thought about looking for Firefox, but there are plenty of other Gecko-based browsers. So I thought, maybe "Gecko."

But, oh, wait. Chrome reports, among other things, that it is "KHTML, like Gecko."

So I ended up having to check for "Gecko" and then make sure that it wasn't "like Gecko."

If you're interested, here's the code I used...

if(navigator.userAgent.match(/Gecko/i) && !navigator.userAgent.match(/like Gecko/i)){ // Must be dealing with Firefox, etc.

Just because life in webdev land can't be easy.

Saturday, September 18, 2010

jOverviewMapControlV3

In my last post, I discussed a recent project in which I was porting a project which relied on Google Maps API v2 to Google Maps API v3 and the problems I ran into trying to utilize the LocalSearch component of Google's AJAX Search API with the new version of the Maps API. In this post, I want to talk about the second major pitfall I ran into while working on this project: several key features of v2 have not (yet) been added to v3.

Now, in most cases, this is inconsequential, to say the least. The Maps API dev team established performance as a higher priority than making sure the API included three different styles of kitchen sinks, so they eliminated some of the not-as-utilized features of the API, and v3 screams compared to the rusty groan of v2's bloated code as a result! (Read that, v3 is AWESOME and WELL WORTH the jump!)

But I do miss at least one of the features that they omitted this time around: the GOverviewMapControl. In fact, for the project that I was working on, the client specifically requested the overview map that appears in the lower-right corner on http://maps.google.com and gives you at least some semblance of where you are in the world when using the larger map. So this wasn't just a trivial thing for me. I needed an overview map control.

So I went searching, and I found an issue on the GMaps issues list where people requested this exact feature. As of this writing, 83 people had starred the issue, meaning that they wanted it. And in fact, it was actually "acknowledged" by the dev team. Unfortunately, though, the issue was created July 2009, acknowledged a day later, and now, over a year later, there is still no overview map in GMaps v3.

Considering that the project was not at the top of my priority list, I didn't worry about it too much. I simply starred the issue and decided to work around it as best I could, hoping that, by the time I was ready to finish the app, the control would be included in the v3 code. Alas, however, I reached a point this week where I was wrapping things up and still needed the control.

So I wrote one.

For anyone still looking for an equivalent to the GOverviewMapControl in Google Maps API v3, I've created a new Google Code project for my solution, which you can check out at http://code.google.com/p/gmaps-api-v3-overviewmapcontrol.

As with the last post (check it out here), though, I will take a couple of seconds to make some notes.

First, I did take a couple of "liberties" to make my version a bit more fun. Namely, I animated the opening and closing, and I made it automatic. This is the default behavior. In the next couple of days, I think I will make the automatic opening and closing optional. Maybe I'll make the animation optional, too. I just haven't decided on that part yet.

Second, you may notice that, when you drag the polygon to the edge of the overview map, the overview map does not pan automatically. This is something that I have thus far been unable to do smoothly. If you have any thoughts on how I could accomplish this, I would love to hear them.

Third, I am aware of an issue where releasing the polygon after dragging it around does not trigger the event to move the map. I'm working on it. If you have any ideas on fixing it, let me know.

Fourth, there is no fourth note. I just inserted this paragraph for kicks. It kind of breaks up the list of notes and gives me a chance to use the word "sixth" in a blog post.

Fifth, because I have no special permission from the GMaps team, I have made no effort to eliminate the Google logo and terms notices on the overview map. These do eat up screen real estate, but they also make sure that the Google Legal (Beta) team doesn't come after me.

And sixth, you should be aware that I am using a real hack to put the control on the map. Namely, this control is not added to the map by pushing it into one of the 8 custom control trays. Rather, it is simply appended to the map parent div. So you have complete control over where it is placed, etc., in the CSS. In theory, you could put it front and center on your map, or you could use it to cover one of the essential components of the map (e.g., the Google branding and/or licensing notices). I assume no responsibility for any consequences you may incur by changing the positioning rules specified in the default.css file.

So there you have it. An overview map control for GMaps API v3. Now go and map something!