A Flickr-like static zoomable map component
I love web maps. I've been working and tinkering with them since the days before Google Maps and it has been great to see all the evolutions the field went through. Now interactive maps are everywhere and the tools to build them are more varied than ever. I like discovering new kind of maps or complex map-based visualizations everyday. Especially those with nice looks and good UX, and which respect the cartographic principles.
But even more than these full-featured experiences, I love more subtle uses of maps on the web. Flashy dataviz and big slippy maps with tons of overlays aren't the answer to everything. There are use cases where leaner, more original solutions fill the needs more elegantly.
The Flickr mini-map
A perfect example I've always been a fan of, is the small map widget that Flickr uses to display the location where a geo-tagged photo has been taken. Like on this photo by my friend Pierre.
Being so small, it fits nicely in the metadata panel and doesn't get in your way when looking at the photo. It just shows the photo's position at a roughly continental level, which is already useful. If you're interested in knowing more about the photo's location, you would naturally hover it with your cursor. There, it zooms progressively to the precise location, as the mouse moves closer to the center. As the changing cursor shows, the whole component is also a link. Clicking it opens a full slippy map at the location, if you want to explore the surroundings freely.
There is a lot of depth and interactivity in such a small widget. And all of that without any additional interface element like zoom buttons or slider. It's also light from a technical point of view. Being made of only three images and very simple JavaScript, it doesn't add much to the page weight and loading speed.
My version
You got it, I'm fond of this Flickr mini-map. But I've never seen it anywhere else than on Flickr. So I decided to make a clone it, and of course to make if more parametrizable.
Here it is, a new dev project: react-staticMapZoom (yes, React. More on that below).
It takes a center coordinate and a few more parameters.
- Support for different map providers. For now, default map styles from Google Maps, Mapbox and OpenMapQuest. I'll add more settings to specify custom styles and support the other common static map providers.
- The Flickr widget uses the same three zoom steps on all pages. Here you can use whatever number of steps and use any zoom level supported by the provider.
- You can assign a custom link on click. If not, it becomes a simple unclickable
div
. - You can display a reticle around the map center.
Under the hood
I release it as a React component because I want people to use it. React is the most active and credible paradigm in web development today, and even if its model doesn't bring much to such a simple and atomic case[1], at least the component will fit in the ecosystem. The fact that I use React everyday at work may have helped too :)
Conceptually, the component is really simple. It's basically a stack of static images, one by zoom level, wrapped in a container element. The image URLs are calls to the choosen API, built with simple template strings.
For the mouse behavior, I attach a mouse listener to the container and define smaller and smaller rectangular areas down to the center (no DOM elements are created, it's just number values). As the center-most areas are hovered, the top-most images disappear. When the cursor is in the smallest area, only the image at the bottom of the stack (i.e. the higher zoom level) is visible.
To hide the images, I set their opacity
to 0
. A transition
property gives a nice cross-fade effect.
And that's all for how it works. Actually the main technical part was everything else: setting up an environment for React, transpiling and building, testing, packaging for distribution, etc., i.e. all that makes JavaScript development in 2016 – for better or worse.
Some useful resources I used to see clearer:
- Wishlist for distribution of reusable React components
- Distributing React components
- Refactoring React Components to ES6 Classes
- Testing ES6 Modules with Mocha using Babel with Browserify
Actually, I had implemented a first version last year as a Web Component, but I wasn't happy with the result. Maybe in the future, if the spec gets better. I may also release a vanilla JS version. ↩︎