Leaflet/Leaflet — pull request #2786 by Jakobud (2014-07-10 05:52:26+00:00)
Title: Pane management: huge refactoring and rewrite!

I've been messing with the master branch recently, eager to see the new Pane management features but was disappointed to see that you could not yet assign vector elements to custom Panes (#2779).

Well I started diving into the code to see what I could learn and improve and here are the results. I have completely rewritten the way that Panes work. Currently, Panes are simply DOM elements/containers, for example:

```

```

The problem is that, in the current state, Leaflet cannot put vector elements on any pane other than the `overlayPane`. The reason is that the map only uses a single Renderer, who's container would always show up on the `overlayPane`, even if you assigned a different or custom pane to a vector element as you created it. So therefore, all vector elements get added to the `overlayPane` since that is where the renderer's `svg` (or canvas or whatever) container was.

The solution is that Leaflet needed the ability to use multiple renderers, one for each pane that any vector elements existed on. Keeping track of multiple renders on panes being just DOM elements was tricky...

### A new class.... L.Pane
Therefore I created a new class/object `L.Pane`. With this commit, panes are no longer simple DOM elements. They are now objects, that have a container and (potentially) a renderer. Moving to this type of setup allowed me to easily keep track of which panes already had renderers when adding vector elements to the map. Also, the Pane class approach will allow for some more flexibility and additions in the future.

- Panes are still created using the `map.createPane()` method. It take the same arguments but does things different under the hood (creates a `L.pane` object).
- `map.getPane()` and `map.getPanes()` are still used the same way.
- `map.getPane('myPaneName')` if the pane doesn't exist, out of convenience, it will be created for you automatically. This saves you from needing to create panes manually before assigning layers to them. Just specify a pane for a new layer and it will be created for you if it doesn't already exist.
- `map.paneExists()` check if a pane exists or not.
- To add a DOM element to a pane, use `myPane.add(myDomElement)`
- To remove a DOM element from a pane, use `myPane.remove(myDomElement)`
- If you need to get the actual DOM element/container of a pane use `myPane.getContainer()`. This is used several places in the source, for example, whenever the `mapPane`'s container needed to be transformed.
- Access a pane's container's css styles: `myPane.style.zIndex = 10`.
- When adding a vector layer to a pane (any pane you want, even custom ones), `map.getRenderer()` will now fetch the renderer from the vector layer's assigned pane. If a renderer on that pane already exists, it will use that. If not, it will create it.
- If you don't specify a pane for Vector layers, they end up on the `overlayPane` by default, just like they currently do.

@mourner I don't know what plans you had exactly for Panes, but I've put a lot of time and thought into this and I think this is a really good approach. It adds new features (vectors can now use custom panes too!!) and also using Panes as objects will allow for some more features in the future. Give it a shot! What do you think?