Showing a region of the Canvas
Sometimes you want to render just a part of an image (an xywh
region).
This might be part of a Canvas, or a region of an image service. This can be specified with the region
parameter, available on both image-service
and canvas-panel
:
If you just have an image service:
If you have a canvas ID, within a manifest:
Another variation is a content state that supplies the canvas, but doesn't supply a region:
And if that content state does supply the region itself, then it's all you would need:
(See this content state decoded)
In the example immediately above, that content state expands to this:
{
"id":"https://iiif.wellcomecollection.org/presentation/b14658197/canvases/b14658197.jp2#xywh=2449,1062,1695,965",
"type":"Canvas",
"partOf":[
{
"id":"https://iiif.wellcomecollection.org/presentation/b14658197",
"type":"Manifest"
}
]
}
That is, region 2449,1062,1695,965
, on the canvas https://iiif.wellcomecollection.org/presentation/b14658197/canvases/b14658197.jp2
, which is in the manifest https://iiif.wellcomecollection.org/presentation/b14658197
. (This example taken from Content State specification).
If the preset
behaviour of canvas panel is set to static
or responsive
, you don't need any additional attributes. But if rendering as deep zoom (the default render
), that implies you can zoom within the viewport provided; but we might want to prevent you panning outside the initial region (or might allow it, as required).
The attribute that makes Canvas Panel restrict panning outside of the region (when in zoom mode) has not yet been implemented.
If a full-screen mode is available and the user activates it: what fills the screen and what are the constraints on panning? For all render modes, if the target
of that content state was a region of canvas (e.g., ..#xywh=900,900,1000,1000
), then it will initialise with that as a best-fit, which might show areas outside the region.
How to make the viewport go full screen?
Full screen is a user-land feature that could be added:
Setting regions programmatically
Canvas Panel always shows one canvas. That canvas is accessible via the Vault. However, that canvas might be a synthetic canvas that the developer dynamically and composited other canvases and content onto. Your app might be using a wrapping layout component around Canvas Panel, e.g., to layout a manifest as a strip (with zones) so you don't have to explicitly do the compositing.
Introducing Targets
The simple version of a Target class shown here is supported by the current Canvas Panel.
We are working on a more sophisticated Target class (that could be be any spatial or temporal target on a Canvas).
As well as setting region via an attribute, you can also set it in code. The region
attribute is a 2D-specific simplification of a more general Target
helper class. Here we are creating a Target instance ourselves to specify a part of the canvas.
const myTarget = { x: 0, y: 0, width: 100, height: 100 };
cp.goToTarget(myTarget);
const myTarget2 = { x: 2000, y: 2000, width: 2000, height: 1500 }
const myOptions = { padding: 20, nudge: true, immediate: true }
cp.goToTarget(myTarget2, myOptions);
The following is not yet supported:
const myTarget2 = { x: 2000, y: 2000, width: 2000, height: 1500 }
const myOptions = {
padding: 20,
nudge: true,
transition: "transform 500ms ease-out"
}
cp.goToTarget(myTarget, myOptions);
// The syntax of transition is the same as CSS transition
// https://developer.mozilla.org/en-US/docs/Web/CSS/transition
You can also remove the target, and there is a built-in home target, to return canvas panel to its initial state (returning to the viewport as it was initially, before panning and zooming):
cp.clearTarget();
cp.goHome();
For more on developing Annotation functionality, displaying annotations, and working with bodies and targets, see Annotations.
More with regions
This image shows the sort of widget that might be used in a content management system, where the editor can select either a whole image (the top one) or a detail of a larger image (the bottom one), and accompany that image with some additional HTML.
This is an example of using Canvas Panel as a component of some other piece of software - Canvas Panel itself doesn't render the additional markup - that's the component you write. Canvas Panel takes care of rendering a canvas, or some part of a canvas.
Using content state
In the following, https://iiif-canvas-panel.netlify.app/extra-fixtures/boy-with-straw-hat.json
is a content state at a URL. This will have been made by an editor at content-creation time, using a Content State Selector. It's a full JSON content state that looks like this:
{
"type": "Annotation",
"motivation": ["contentState"],
"target": {
"id": "https://iiifmediawiki.herokuapp.com/presentation/canvas/c208117.json#xywh=50,990,2100,1755",
"type": "Canvas",
"partOf": [
{
"id": "https://iiifmediawiki.herokuapp.com/presentation/File:Baigneurs_a_Asnieres.jpg",
"type": "Manifest"
}
]
}
}
The content-management template author will then produce code that will output something like this:
<div class="canvas-figure">
<canvas-panel
preset="responsive"
iiif-content="https://iiif-canvas-panel.netlify.app/extra-fixtures/boy-with-straw-hat.json"
/>
<p class="figure-text">
Fig. 75<br/>
Georges Seurat (1859-1891)
<strong>Bathers at Asnières 1884 (detail)</strong><br/>
<em>Oil on Canvas</em><br/>
24.1 × 31.1 cm (9 1/2 × 12 1/4 in.)<br/>
The National Gallery, London<br/>
</p>
</div>
That is, the content-managed data for this widget is the figure text, and a content state pointing to the relevant part of an IIIF resource.
As the template author has the content state handy, they can use it to create a link to another page that would let the user explore the painting in mode detail (but still initialised on the boy-with-straw-hat detail):
<a href="https://getty.edu/iiif-viewer?iiif-content=https://iiif-canvas-panel.netlify.app/extra-fixtures/boy-with-straw-hat.json">View this painting</a>
or, make the canvas panel image the link:
<a href="https://getty.edu/iiif-viewer?iiif-content=https://iiif-canvas-panel.netlify.app/extra-fixtures/boy-with-straw-hat.json">
<canvas-panel
preset="responsive"
width="300"
iiif-content="https://iiif-canvas-panel.netlify.app/extra-fixtures/boy-with-straw-hat.json"
/>
</a>
Not using content state
An alternative would be where the developer has the region and IIIF information to hand directly, in which case they don't need a stored content state, or they are using the info from the content state directly:
Discuss on GitHub