Thanks @fredj for the inspiration. This gives us initial rotation support. It exposes some issues in the interactions that I'll address separately. Closes#22.
When zooming to a new zoom level, we can immediately remove tiles from the previous level. This (strongly) suggests not adding images to the container until they have actually loaded.
We only want to adjust things that have to do with rendering (like the position of the layers panel) when actually rendering. The handleXChange methods may be called more times than we can actually render, so we never want to do anything that touches the DOM there. Instead, we have to keep track of the state at previous render and adjust the layers panel (or other) based on changes only when rendering.
When zooming or panning, if we have tiles at alternate resolutions, those tiles are inserted in the DOM before the tiles at the target resolution. This means you should see blurry tiles instead of whitespace when panning (assuming you've already zoomed in a bit).
Tile pruning code separated into to methods for clarity. Alt-z tiles are only removed when all current-z tiles have loaded. Thanks @elemoine for the excellent debugging session.