Skip to main content

Quick start

What is Canvas Panel?

Canvas Panel is a Web Component that renders a IIIF Canvas and the annotations on it. If you already know what Canvases and Annotations are you are ready to get started. If not, here's a brief introduction with links to more learning resources.

Canvas Panel is not a IIIF Viewer, like Mirador or Universal Viewer. It's not a full application - it's a component of your application. On its own, Canvas Panel doesn't render a IIIF Manifest - but it can be used as the rendering surface in any kind of IIIF application you want to build. You can see Canvas Panel used this way in some of the demo applications. It also provides a powerful API for drawing annotations on the canvas and responding to user interaction with the canvas.

You can see how to use Canvas Panel to build a Manifest Viewer in some of the later application examples.

How do I get Canvas Panel?

An easy way to try things out is to simply include a reference to Canvas Panel on (CDN). See Installation for more options.

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@digirati/canvas-panel-web-components@latest"></script>
</head>
<body>
<h1>Canvas Panel</h1>
<canvas-panel id="cp"></canvas-panel>
<script>
// drive canvas panel here...
</script>
</body>
</html>

Basic usage

The most common scenario is simply rendering a Canvas. Most canvases live in Manifests rather than on their own on the web, which means "show this canvas in that manifest" is a common pattern:

<canvas-panel
canvas-id="https://digirati-co-uk.github.io/wunder/canvases/0"
manifest-id="https://digirati-co-uk.github.io/wunder.json">
</canvas-panel>

This shows Canvas Panel loading a manifest, finding a particular Canvas, and rendering that Canvas with the familiar pan-and-zoom behaviour expected for IIIF image content. It will do this even if the canvas is a complex scene composed of several source images! In this respect Canvas Panel is different from OpenSeadragon and Leaflet. In those libraries, your code would need to evaluate the canvas content and render it all manually. Canvas Panel understands IIIF Canvases natively, so you just give it a Canvas.

In this simplest form, with no additional attributes, it is like OpenSeadragon and Leaflet in that it renders a viewport, in which the canvas (or a part of it, if zoomed in) is visible. This is the mode you might use in a viewer application.

Canvas Panel is also an IIIF-aware alternative to image tags, and can be automatically responsive:

<canvas-panel
preset="responsive"
canvas-id="https://digirati-co-uk.github.io/wunder/canvases/0"
manifest-id="https://digirati-co-uk.github.io/wunder.json">
</canvas-panel>

These behaviours are explained in more detail in Responsive Images and rendering modes.

Canvas Panel generally fills up the available width, with a default height. You can use this to adjust the size of canvas panel on the page:

<div style={{ maxWidth: 400 }}>
<div style={{ marginBottom: '10px' }}>
<canvas-panel
preset="responsive"
canvas-id="https://digirati-co-uk.github.io/wunder/canvases/0"
manifest-id="https://digirati-co-uk.github.io/wunder.json">
</canvas-panel>
</div>

<div style={{ marginBottom: '10px' }}>
<canvas-panel
preset="responsive"
canvas-id="https://digirati-co-uk.github.io/wunder/canvases/0"
manifest-id="https://digirati-co-uk.github.io/wunder.json"
region="466,2221,1612,450"
exact-initial-image="true">
</canvas-panel>
</div>
</div>

You can also render the viewport statically, without the pan and zoom behaviour:

<canvas-panel
preset="static"
canvas-id="https://digirati-co-uk.github.io/wunder/canvases/0"
manifest-id="https://digirati-co-uk.github.io/wunder.json">
</canvas-panel>

The addition of preset="static" changes the behaviour of the component on the web page; now you can't zoom in. This becomes more useful when combined with other behaviours later.

The above examples use presets - with the default being zoom.

Note that the second of the two canvas panels above uses the region attribute to render just one part of the Canvas.

Getting content in

The canvas-id and manifest-id attributes are helpers for a very common scenario for loading a canvas into Canvas Panel: when you know the manifest URL, and you know the ID of the canvas within it, but the canvas is not dereferenceable on its own.

More generally, you can use the iiif-content attribute, which accepts a Content State - this allows any IIIF Content State that references a Canvas, or part of a Canvas, to be used to initialise Canvas Panel.

<canvas-panel
iiif-content="JTdCJTB...[omitted for brevity]...MEElN0Q">
</canvas-panel>

Examples of content states are bookmarks and search results. You can see what the content state used in the above example looks like in a content state decoder.

tip

A simple Manifest URL is a valid content state. These should not be encoded. But the IIIF Content State Specification requires that complex content states like the above, that are JSON objects, must be encoded - as in these examples.

However, Canvas Panel also accepts these complex content states as values of the iiif-content property in unencoded form, to help with debugging and experimenting:

<canvas-panel
iiif-content='{"id": "https://digirati-co-uk.github.io/wunder/canvases/1","type":"Canvas","partOf": [{"id": "https://digirati-co-uk.github.io/wunder.json","type": "Manifest"}]}'
/>

This approach should not be taken in production, but it is useful when testing content states before encoding.

Content states can be used to point at any part of a Canvas:

Programming Canvas Panel

You can also work with the Canvas from script. This is more typical in client-side applications. The attribute-based approach is more useful in rendering IIIF content server-side. You can tell Canvas Panel to do the same thing as the attributes above like this:

import '@digirati/canvas-panel-web-components';
import './styles.css';
 
const manifestId = "https://digirati-co-uk.github.io/wunder.json";
const canvasId = "https://digirati-co-uk.github.io/wunder/canvases/2";
const cp = document.getElementById("cp");

cp.vault
    .loadManifest(manifestId)
    .then(manifest => cp.setCanvas(canvasId));

What is Vault?

By default, all canvas-panel elements on the page share a common instance of a Vault. The Vault library is used to load and manage IIIF resources, rather than passing them directly to Canvas Panel as JSON blobs. In the example above, we load a IIIF Manifest into the same vault, which we can obtain from Canvas Panel. Then we tell Canvas Panel to display a canvas from this manifest. This is simpler and safer than loading the manifest yourself, as JSON via fetch(), determining its version and traversing it.

Under the hood, Vault manages the HTTP fetch operations and optimises internal storage of all the IIIF resources in use on a page. Vault normalises all IIIF to the Presentation 3 specification, allowing you to take advantage of a consistent programming interface regardless of the source IIIF. Vault also has the advantage of making your IIIF strongly-typed when used via TypeScript.

Read more about Vault here. Vault is now part of IIIF Commons.

Getting started with making a Viewer

One of the most common tasks is building viewers - where we load a IIIF Manifest and allow the user to navigate around the different Canvases (views) within it. You can explore Canvas Panel's features in the docs, or go straight to Building a Simple Viewer to follow along.

Canvas Panel as part of a wider set of tools

A larger IIIF application like a viewer, manifest editor or annotation tool will certainly get a lot of benefit from using Canvas Panel.

What happens visually on Canvas Panel is a reflection of the data in Vault. Canvas Panel's own API is a mixture of styling and behaviour control, and operations that modify Vault data.

In a larger application, you are likely to be manipulating Vault data via additional mechanisms, additional UI surfaces beyond Canvas Panel, but still see the effects of that manipulation reflected in Canvas Panel. For example in a React or Vue application, UI controls are bound to data in Vault, and Canvas Panel changes in response to Vault data; you might not interact with Canvas Panel's own API much.

In a simpler application, Canvas Panel's API is more useful; it (and vault-helpers) fulfil common scenarios.

Canvas Panel aims to be a slice through a larger space of possible functionality, encapsulated in a web component. Being a web component is very powerful and simple, but it does constrain development style; there are things more easily done by bypassing the Canvas Panel API.

Image Service and Layout helpers

The Canvas Panel library also includes a web component for use when you only have the IIIF Image API - when you don't have a Canvas. It takes most of the same attributes, but has a src property that points to an image service, rather than canvas references or content states.

<image-service 
preset="responsive"
src="https://iiif.wellcomecollection.org/image/L0007430">
</image-service>

Read more about this component at in Responsive Images and rendering modes.

A further component is available to help with layout: positioning more than one image service or canvas next to each other:

<layout-container width="800" preset="zoom">
<image-service nested src="https://iiif.wellcomecollection.org/image/b18035723_0010.JP2" x="0" />
<image-service nested src="https://iiif.wellcomecollection.org/image/b18035723_0011.JP2" x="2411" />
</layout-container>

Read more about this component in Layout Container.