This is a beta version of migrating these workshop materials to a new platform. If you run into issues please file an issue or click on the edit link above and submit a pull request. You can use the previous version of the workshop materials as a fallback.
A canvas is a coordinate space on which images can be painted. Images are painted onto a canvas through annotation. In the simple case we’re only painting a single image annotation so that it fills the whole canvas. But the canvas also makes it possible to paint multiple images onto the same canvas as well as overlay additional annotations.
In order to deliver with these embedded annotations, there’s no requirement to have any particular annotation infrastructure available. You do not need to have an annotation store. These embedded annotations can usually be created without a graphical user interface. There’s also no requirement in IIIF to provide for users to create or manage annotations.
See the sections on shared canvas and manifest structure for more information on what a canvas is and how it fits into a manifest.
canvases
PropertyEach sequence can be made up of more than one canvas. So first we’ll add a canvases
property to our sequence with a value of a list.
So our sequence will now look like this:
{
"@type": "sc:Sequence",
"canvases": [ ]
}
Next we’ll add our single canvas. So create an empty object within the canvases
list:
{
"@type": "sc:Sequence",
"canvases": [ {} ]
}
The @type
of our canvas should be sc:Canvas
:
{
"@type": "sc:Sequence",
"canvases": [
{
"@type": "sc:Canvas"
}
]
}
The @id
for a canvas is required. We need this identifier in place so that when we later add an annotation to the canvas we have the reference to the canvas.
The strong recommendation is that the identifier for the resource be dereferencable. That means that it be possible for a client to request the URI for the canvas and have the canvas resource returned. Having dereferencable canvases allows for better reuse of canvases, a key piece to the IIIF landscape. This is the best practice.
In the case of this workshop we will not create the canvas as a separate dereferencable resource. That is, if you try to request the resource at the URL we give to the canvas you won’t get anything back as there’s nothing there.
{
"@type": "sc:Sequence",
"canvases": [
{
"@type": "sc:Canvas",
"@id": "http://localhost:3000/segPap_022/canvas/1"
}
]
}
A canvas is required to have a label
property that clients are required to display. Usually this will be a page number or very short description of the view.
In our example we have the 22nd page image or plate so, we’ll just give it a string label of “22”.
{
"@type": "sc:Sequence",
"canvases": [
{
"@type": "sc:Canvas",
"@id": "http://localhost:3000/segPap_022/canvas/1",
"label": "22"
}
]
}
We also want to add the width
and height
of the coordinate space for our canvas. These dimensions give us the aspect ratio of the object.
Question: What does the specification say about what the width and height of the canvas ought to be? (Hint: In our case we are only adding to the canvas a single image that depicts the page.)
Question: Where might we find dimensions to use for our canvas?
Add a width
and height
property to the canvas. Note that in JSON numbers do not need to be in quotes like text does.
Now with our dimensions added, your sequence ought to look like this:
{
"@type": "sc:Sequence",
"canvases": [
{
"@type": "sc:Canvas",
"@id": "http://localhost:3000/segPap_022/canvas/1",
"label": "22",
"width": 6099,
"height": 8599
}
]
}
We’ve now nested our canvas within our first sequence within the manifest. We’ll have more nesting like this as we go further along. This deep nesting may be one of the more difficult pieces of the IIIF Presentation API to understand and remember. The diagrams in the specification can help remember the ordering: http://iiif.io/api/presentation/2.1/#resource-type-overview. Or refer back to manifest structure.
manifest
sequences
canvases
images
resource
service
We now have completed a basic canvas you can see below.
If we were going to make our canvas available separate from our manifest we’d also need to add the IIIF @context
, so we’ve added that as well here. This is the same context we used at the top of our manifest. Note that the @context
doesn’t need to be included if the canvas is embedded within the manifest.
{
"@context": "http://iiif.io/api/presentation/2/context.json",
"@type": "sc:Canvas",
"@id": "http://localhost:3000/segPap_022/canvas/1",
"label": "22",
"width": 6099,
"height": 8599
}
{
"@context": "http://iiif.io/api/presentation/2/context.json",
"@type": "sc:Manifest",
"@id": "http://localhost:3000/manifest.json",
"label": "Papillons",
"description": "Four patterns inspired by butterflies.",
"attribution": "Special Collections Research Center at NCSU Libraries",
"logo": "http://localhost:3000/logo.jpg",
"sequences": [
{
"@type": "sc:Sequence",
"canvases": [
{
"@type": "sc:Canvas",
"@id": "http://localhost:3000/segPap_022/canvas/1",
"label": "22",
"width": 6099,
"height": 8599
}
]
}
]
}