Rrose: A Leaflet Plugin for Edge Cases

View the Project on GitHub erictheise/rrose

What is this?

Rrose is a plugin for the Leaflet JavaScript Mapping Library. It's useful when you want popups to respond to the mouseover event, but the behavior associated with autoPan is getting in your way.

Here's a typical Leaflet map. If you click on the map, you get a popup containing a random word (courtesy Wordnik). Note that when you click close to the top, left, or right side of the map, the map moves to accommodate the space required to display the popup. This is autoPan, one of the awesome features built into the Leaflet library that makes maps look good from the git-go.

But suppose you'd like popups to respond to mouseover, so that you can quickly scan the shortlist of a map's attributes, reserving the click event to display the details. In this case, autoPan ceases being your friend; mousing over the top, left, or right side of the map can kick off an escalator ride as autoPan clears room for your popup, leaving you in a new region, which triggers a new popup, & so on. It makes your map feel jittery and out of control.

Setting autoPan : false triggers a different problem; popups at the top, left, or right edge of the map end up offscreen, unreadable.

This is the problem that Rrose aims to solve. What we would like is for the popup to appear under (south of) the point when we're too close to the top, and for it to appear to the left or right (west or east of) the point when we're too close to the sides. The scheme looks something like a compass rose, and the plugin takes its name from Marcel Duchamp's alter ego, Rrose Sélavy:


This behavior will be familiar to you if you've worked with popups in OpenLayers or other mapping libraries. Here it is in action:

Using it

This demo page was updated on 27 Sep 2016, concurrent with the release of Leaflet 1.0.0. If you can't upgrade to that major release, make sure you're using Leaflet 0.7.2 or higher, or 0.6.2 or lower. A bug in Leaflet releases 0.6.3, 0.6.4, 0.7, and 0.7.1 prevented Rrose from working properly.

Drop leaflet.rrose-src.js alongside leaflet-src.js, and leaflet.rrose.css alongside leaflet.css. (If you need to use Leaflet 0.6.2 or lower, use Rrose release v0.1.0 and include leaflet.rrose.ie.css conditionally, as you would with leaflet.ie.css. This requirement was dropped with Leaflet 0.7.X and, as such, is no longer mirrored in Rrose.) Then, instead of instantiating a new L.Popup object, instantiate a new L.Rrose object:


onEachFeature: function(feature,layer){
  layer.on('mouseover mousemove', function(e){
    var hover_bubble = new L.Rrose({ offset: new L.Point(0,-10), closeButton: false, autoPan: false })
  layer.on('mouseout', function(e){ rrose_map.closePopup() });