Updated 2018 - Please see http://canvas-panel.digirati.com/#/about for later developments. The conversation on this gist is kept here for its usefulness to posterity...
There is a resuable component that sits between tile renderers like OpenSeadragon (OSD) and manifest-level viewers. This component can be reused in very simple IIIF-powered applications - a few lines of JavaScript - but is sophisticated enough to form the basis of custom applications with complex layout and annotation rendering requirements.
I'm not quite sure what its external interface looks like yet - but it's the component I'd reach for to make an ad-hoc IIIF powered mini-application instead of OSD because it understands canvases directly. Under the hood it's wrapping OSD (or another tile renderer).
This is a component that provides a surface for rendering one or more sc:Canvas objects and the image annotations on them. So it's both a library (or combination of libraries) and a UI component that takes up screen space. It takes care of all the rendering, relative positioning, scaling, support for tiled and single images, oa:Choice, oa:SpecificResource etc within a canvas, but leaves the layout of multiple canvases under your control.
It's like OSD, and feels a lot like OSD for the developer - but it deals with sc:Canvas resources "natively" rather than tileSources. A likely first implementation would be a wrapper around OSD.
It could be instantiated in a similar way to OSD:
cp = canvasPanel({container: $('#cp')});
cp.addCanvas(myManifest.sequences[0].canvases[0]);
By default it would render the canvas to fill the world - but just as with OSD multi-tile source you can drive it for any kind of positioned or animated layouts - masonry-style, whatever. It helps you with layout in the same way OSD offers a world for multiple tileSources - but it's your decision (e.g., if you want to build things like http://iangilman.com/openseadragon/flickr/, you can).
It can also plot the bounding rectangles or svg shapes for any other non-image annotations you load (whether by following otherContent or loading arbitrary external lists), but leaves the rendering of the bodies of those annotations up to you. It gives you hooks for point annotations, hotspots for linking etc. It is the natural foundation for building a bespoke presentation of densely annotated material where the annotation bodies are rich content - it is not concerned with how you render those bodies (although makes it easy to overlay if you want to render on top), but it takes care of managing bounding rectangles or shapes and drawing and scaling them within a "world" of one or more rendered canvases.
It offers a capture surface for points, rectangles and more complex shapes, but leaves everything else up to the containing application. That is, it can be switched into a mode that a containing application could use to capture an annotation from a user. Not sure if it supplies its own drawing tools.
The visibility, appearance, animation effects etc of any annotations it displays are completely controllable externally. It is NOT concerned with how you capture the body of an annotation from a user (e.g., text boxes, forms etc). That's your UI to worry about.
It might be used as the rendering surface of a viewer that understands things at the manifest level - e.g., it could be the centre panel of UV or Mirador), but on its own it doesn't know anything about ranges, sequences or other presentation API resources. You would need to build an application and bring in other libraries for that.
While the containing application is responsible for understanding how annotationLists are grouped into layers, the interface exposed by canvasPanel makes it easy to show and hide individual annotations, whole lists, or sets of lists. That is, show the bounding shape and offer affordance for selection. How they are shown and hidden (fades, animations etc) needs to be externally controllable.
// not really sure what this looks like yet...
cv = myManifest.sequences[0].canvases[0];
cp.addCanvas(cv);
// a wrapped annotation ref?
cpAnno = cp.show(cv.annotationLists[0].findById("@..."));
cpAnno.hide();
// and a list
cpAnnoList = cp.show(cv.annotationLists[2]);
cpAnnoList.hide();
// I have my own annos on this canvas as well
myAnnos = loadExternalAnnos("http://myannos.com/list");
cp.show(myAnnos);
It doesn't need to know about manifests and collections, it's a surface for rendering canvases. Complex layouts are driven externally. It clearly intersects significantly with iiifManifestLayouts. In fact you could take iiifManifestLayouts and reshuffle it - the code in canvasObject.js, canvasUtils.js, imageResource.js, imageResourceFactory.js etc becomes the canvasPanel wrapper round OSD and the manifest(or)-level code then lays out the canvases on the panel via the canvasPanel abstraction rather than directly.
canvasPanel is an interface. It fires events, it exposes functions. You can make an OSD version, a leaflet version, whatever. But the abstraction level of its interface is at the canvas level, not the tilesource level. This is what makes it powerful for quick IIIF-powered user interfaces.
This is meant to be IIIFManifestLayouts. The layout functions themselves are pure functions, and have been broken out into this library, which needs a better name. We certainly need some refactoring to separate the bits of OSD-specific code that have crept into the canvasObject/canvasUtils/imageResource files, with a focus on events. I would also be very happy if the single-canvas components of this were separated into yet another separate component with its own tests, demo pages and self-contained API.
Please see these briefs [1] (the thumbnail generation part of that needs to be rewritten, see #116, [2] about these components of IIIFManifestLayouts.