API Reference: Annotorious
The standard version of Annotorious works with normal images embedded in websites or web applications. If you are looking for the Annotorious OpenSeadragon plugin, see here instead.
Initialization
When included via <script>
tag:
var config = {
image: document.getElementById('my-image'),
readOnly: true
};
var anno = Annotorious.init(config);
With npm:
import { Annotorious } from '@recogito/annotorious';
import '@recogito/annotorious/dist/annotorious.min.css';
const config = {
image: document.getElementById('my-image')
}
const anno = new Annotorious(config);
The config object supports the following properties:
Property | Type | Default | Description |
---|---|---|---|
allowEmpty |
Boolean | false | Annotations created without bodies are normally discarded. Set to true to allow empty annotations. |
crosshair |
Boolean | false | When the mouse is over the image, show a crosshair instead of the mouse cursor |
disableEditor |
Boolean | false | Disable the editor if you only need drawing functionality, but not the popup. |
disableSelect |
Boolean | false | Disables selection functionality. Clicking will no longer open the editor. (The clickAnnotation event still fires.) |
drawOnSingleClick |
Boolean | false | If true users can start drawing with a single click also, not just with click-and-drag |
formatters |
Array | Function | - | A formatter function or list of functions providing custom style rules. |
fragmentUnit |
String | ‘pixel’ | Store rectangle coordinates in pixel units (default) or percent units. |
handleRadius |
Number | 6 | Radius of the shape resize handles. |
image |
Elem | String | - | Required. Image DOM element or element ID. |
locale |
String | - | Two-character ISO language code or auto to use the browser setting. |
messages |
Object | - | Custom UI labels. Requires a message dictionary object. |
readOnly |
Boolean | false | Display annotations in read-only mode. |
widgets |
Array | - | A list of editor widget definitions (see this guide for details). |
Instance Fields
disableEditor
console.log(anno.disableEditor); // true or fals
anno.disableEditor = !anno.disableEditor; // toggles state
Change the operation mode between normal (drawing tools & editor popup) and headless. In headless mode, only drawing tools and lifecycle events are active. The editor will not open.
disableSelect
console.log(anno.disableSelect); // true or false
anno.disableSelect = !anno.disableSelect;
Disables selection functionality. Clicking an annotation will no longer open the editor, or fire
the selectAnnotation
event. The clickAnnotation
event will still fire!
Setting disableSelect
to true
will not clear the current selection, if any.
formatters
anno.formatters = [ ...anno.formatters, MyFormatter ];
The formatter functions on this Annotorious instance.
readOnly
console.log(anno.readOnly); // true or fals
anno.readOnly = !anno.readOnly; // toggles state
Change display mode between normal (annotations are editable) and read-only.
widgets
anno.widgets = [...anno.widgets, MyCustomWidget ];
Dynamically changes the current set of editor widgets.
Instance Methods
.addAnnotation
anno.addAnnotation(annotation [, readOnly]);
Adds an annotation programmatically. The format is the W3C WebAnnotation model.
Argument | Type | Value |
---|---|---|
annotation |
Object | the annotation according to the W3C WebAnnotation format |
readOnly |
Boolean | set the second arg to true to display the annotation in read-only mode |
.addDrawingTool
anno.addDrawingTool(plugin);
Register a drawing tool plugin.
.cancelSelected
anno.cancelSelected();
Programmatically cancel the current selection, if any.
Note: programmatic cancel will not trigger the cancelSelected event!
.clearAnnotations
anno.clearAnnotations();
Delete all annotations from the image.
.clearAuthInfo
anno.clearAuthInfo();
Clears the user auth information. Annotorious will no longer insert creator data when a new annotation is created or updated. (See setAuthInfo for more information about creator data.)
.destroy
anno.destroy();
Destroys this instance of Annotorious, removing the annotation layer on the image.
.getAnnotationById
const annotation = getAnnotationById(id);
Returns the annotation with the specified ID.
Argument | Type | Value |
---|---|---|
id |
String | the annotation ID |
.getAnnotations
const annotations = anno.getAnnotations();
Returns all annotations according to the current rendered state, in W3C Web Annotation format.
.getImageSnippetById
const { snippet, transform } = anno.getImageSnippetById(annotationId);
Returns an object containing:
- A DOM CANVAS element with the given annotation’s image snippet
- A coordinate transform function that translates X/Y coordinates in the snippet coordinate space back to the coordinate space of the full image
Field | Type | Value |
---|---|---|
snippet |
Canvas | the image under the given annotations’ bounds as a CANVAS element |
transform |
Function | coordinate conversion function |
.getSelected
const selected = anno.getSelected();
Returns the currently selected annotation.
.getSelectedImageSnippet
const { snippet, transform } = anno.getSelectedImageSnippet();
Returns an object containing:
- A DOM CANVAS element, in the size of the current selection’s bounding box, with the selected image snippet
- A coordinate transform function that translates X/Y coordinates in the snippet coordinate space back to the coordinate space of the full image
Field | Type | Value |
---|---|---|
snippet |
Canvas | the image under the current selection bounds as a CANVAS element |
transform |
Function | coordinate conversion function |
.listDrawingTools
const toolNames = anno.listDrawingTools();
Returns a list of the available drawing tools, including those from registered drawing tool plugins.
.loadAnnotations
anno.loadAnnotations(url);
Loads annotations from a JSON URL. The method returns a promise, in case you want to perform an action after the annotations have loaded.
anno.loadAnnotations(url).then(function(annotations) {
// Do something
});
Argument | Type | Value |
---|---|---|
url |
String | the URL to HTTP GET the annotations from |
.off
anno.off(event [, callback]);
Unsubscribe from an event. If no callback is provided, all event handlers for this event will be unsubscribed.
Argument | Type | Value |
---|---|---|
event |
String | the name of the event |
callback |
Function | the function used when binding to the event |
.on
anno.on(event, callback);
Subscribe to an event. (See Events for the list.)
Argument | Type | Value |
---|---|---|
event |
String | the name of the event |
callback |
Function | the function to call when the event is emitted |
.once
anno.once(event, callback);
Subscribe to an event only once. (See Events for the list.)
Argument | Type | Value |
---|---|---|
event |
String | the name of the event |
callback |
Function | the function to call when the event is emitted |
.removeAnnotation
anno.removeAnnotation(arg);
Removes an annotation programmatically. Note: programmatic remove will not trigger the deleteAnnotation event!
Argument | Type | Value |
---|---|---|
arg |
Object, String | the annotation in W3C WebAnnotation format or the annotation ID |
.removeDrawingTool
anno.removeDrawingTool(id);
Removes the drawing tool with the specified tool ID.
Argument | Type | Value |
---|---|---|
id |
String | the drawing tool ID |
.saveSelected
anno.saveSelected();
Saves the current selection. This is essentially a programmatic way to hit the Ok button on the editor.
.selectAnnotation
anno.selectAnnotation(arg);
Selects an annotation programmatically, highlighting its shape, and opening the editor popup. Note: programmatic select will not trigger the selectAnnotation event!
- If no argument is provided (or the annotation or ID is unknown), this method will deselect the current selection, if any
- The method will return the selected annotation as a result
- Note that the the
selectAnnotation
event will not fire when using this method
Argument | Type | Value |
---|---|---|
arg |
Object, String | the annotation or the annotation ID |
.setAnnotations
anno.setAnnotations(annotations);
Renders the list of annotations to the image, removing any previously existing annotations.
Argument | Type | Value |
---|---|---|
annotations |
Array | array of annotations in W3C WebAnnotation format |
.setAuthInfo
var anno = Annotorious.init({ image: 'my-image' });
anno.setAuthInfo({
id: 'http://recogito.example.com/rainer',
displayName: 'rainer'
});
Specifies user authentication information. Annotorious will use this information when annotations are created or updated, and display it in the editor popup.
Set this data right after initializing Annotorious, and in case the user login status in your host
application changes. The argument to .setAuthInfo
is an object with the following properties:
Property | Type | Value |
---|---|---|
id |
String | REQUIRED the user ID, which should be a URI |
displayName |
String | REQUIRED the user name, for display in the UI |
Annotorious will insert this data into every new annotation body that gets created:
{
type: "Annotation",
// ...
body:[{
type: "TextualBody",
value:"My comment",
purpose: "commenting",
created: "2020-05-18T09:39:47.582Z",
creator: {
id: "http://recogito.example.com/rainer",
name: "rainer"
}
}]
}
.setDrawingTool
anno.setDrawingTool(toolName);
Switches between the different available drawing tools. Per default, Annotorious
provides a standard rectangle tool (rect
) and a standard polygon drawing tool
(polygon
).
More tools may be available through plugins. Use .listDrawingTool to get the list of registered tools.
Argument | Type | Value |
---|---|---|
toolName |
String | E.g. rect or polygon |
.setServerTime
Set a “server time” timestamp. When using authInfo, this method helps to synchronize the
created
timestamp that Annotorious inserts into the annotation with your server environment, avoiding
problems when the clock isn’t properly set in the user’s browser.
After setting server time, the Annotorious will adjust the created
timestamps by the difference between
server time the user’s local clock.
.setVisible
anno.setVisible(visible);
Shows or hides the annotation layer.
Argument | Type | Value |
---|---|---|
visible |
Boolean | if true show the annotation layer, otherwise hide it |
.updateSelected
anno.updateSelected(annotation[, saveImmediately]);
Replace the currently selected annotation with the one given as argument to .updateSelected.
Optionally: save the annotation immediately, triggering a createAnnotation
or
updateAnnotation
event.
Important: this method returns a Promise. The update will not be effective immediately. Make sure you wait until the Promise completes before saving the annotation.
Use this method for applications that (with disableEditor
set
to true
).
var anno = Annotorious.init({
image: 'my-image'
disableEditor: true
});
anno.on('createSelection', async function(selection) {
selection.body = [{
type: 'TextualBody',
purpose: 'tagging',
value: 'MyTag'
}];
// Make sure to wait before saving!
await anno.updateSelected(selection);
anno.saveSelected();
// Or: anno.updateSelected(selection, true);
});
Events
cancelSelected
anno.on('cancelSelected', function(selection) {
//
});
Fired when the user has canceled a selection, by hitting Cancel in the editor, or by clicking or tapping outside the selected annotation shape.
Argument | Type | Value |
---|---|---|
selection |
Object | the canceled selection in W3C WebAnnotation format |
changeSelected
anno.on('changeSelected', function(selected, previous) {
//
});
Fired when the user changed the selection from one annotation to another. Essentially a shorthand.
cancelSelected
and selectAnnotation
will fire in addition.
Argument | Type | Value |
---|---|---|
selected |
Object | the selected annotation |
previous |
Object | the annotation that was selected before |
changeSelectionTarget
anno.on('changeSelectionTarget', function(target) {
//
});
Fired when the shape of a newly created selection, or of a selected annotation is moved or resized.
Argument | Type | Value |
---|---|---|
target |
Object | the W3C WebAnnotation target |
clickAnnotation
anno.on('clickAnnotation', function(annotation, element) {
//
});
Fired every time the user clicks an annotation (regardless of whether it is already selected or not).
Argument | Type | Value |
---|---|---|
annotation |
Object | the clicked annotation |
element |
Element | the clicked annotation SVG shape element |
createAnnotation
anno.on('createAnnotation', function(annotation, overrideId) {
//
});
Fired when a new annotation is created from a user selection.
Argument | Type | Value |
---|---|---|
annotation |
Object | the annotation in W3C WebAnnotation format |
overrideId |
Function | a callback function for assigning a custom annotation ID |
When an annotation is created, Annotorious automatically assigns it a globally unique ID. It is possible to override this ID with your own (e.g. server-generated) ID via the overrideId callback function.
r.on('createAnnotation', async (annotation, overrideId) => {
// POST to the server and receive a new ID
const newId = await server.createAnnotation(annotation);
// Inject that ID into RecogitoJS
overrideId(newId);
});
createSelection
anno.on('createSelection', function(selection) {
//
});
Fired when a new selection shape is drawn on the image.
Argument | Type | Value |
---|---|---|
selection |
Object | the selection object in W3C WebAnnotation format |
deleteAnnotation
anno.on('deleteAnnotation', function(annotation) {
//
});
Fired when an existing annotation was deleted.
Argument | Type | Value |
---|---|---|
annotation |
Object | the deleted annotation |
mouseEnterAnnotation
anno.on('mouseEnterAnnotation', function(annotation, element) {
//
});
Fired when the mouse moves into an existing annotation.
Argument | Type | Value |
---|---|---|
annotation |
Object | the annotation |
element |
Object | the annotation shape SVG element |
mouseLeaveAnnotation
anno.on('mouseLeaveAnnotation', function(annotation, element) {
//
});
Fired when the mouse moves out of an existing annotation.
Argument | Type | Value |
---|---|---|
annotation |
Object | the annotation |
element |
Object | the annotation shape SVG element |
selectAnnotation
anno.on('selectAnnotation', function(annotation, element) {
//
});
Fired when the user selects an annotation. Note that this event will not fire when
the selection is made programmatically through the selectAnnotation(arg)
API method.
Argument | Type | Value |
---|---|---|
annotation |
Object | the annotation in W3C WebAnnotation format |
element |
Element | the annotation SVG shape element |
startSelection
anno.on('startSelection', function(point) {
console.log(point.x, point.y)
});
Fired when the user starts drawing a new shape.
Argument | Type | Value |
---|---|---|
point |
Object | the x/y coordinates of the start point (image pixel coordinates) |
updateAnnotation
anno.on('updateAnnotation', function(annotation, previous) {
//
});
Fired when an existing annotation was updated.
Argument | Type | Value |
---|---|---|
annotation |
Object | the updated annotation |
previous |
Object | the annotation state before the update |
Formatters
Per default, Annotorious renders annotations as SVG group
elements with an a9s-annotation
CSS class. A formatter function allows you to dynamically add additional
attributes and elements to the SVG annotation shape.
A formatter is a JavaScript function takes a single argument - the annotation - and must return a string, a DOM element or an object.
- If a string is returned, it will be appended to the annotation element CSS class list.
- If an object is returned, it should have one or more of the following properties:
className
a string to be added to the CSS class listelement
a DOM element to be appended to the SVG groupdata-*
a data attribute to add to the annotation SVG elementstyle
a list of CSS styles (in the form of a string)
Element Caveats
When using DOM elements, keep in mind that you should specify at least the x,y positions and the width and height attributes.
The x and y positions are calculated from the upper left when using the box tool. If using SVG elements then make sure to use
the appropriate fill/stroke attributes.
String Example
/**
* This simple formatter will add an extra 'long' CSS class to
* long comments
*/
var formatter = function(annotation) {
var longComments = annotation.bodies.filter(function(body) {
var isComment = body.type === 'TextualBody' &&
(body.purpose === 'commenting' || body.purpose === 'replying');
var isLong = body.value.length > 100;
return isComment && isLong;
});
if (longComments.length > 0) {
// This annotation contains long comments - add CSS class
return 'long';
}
}
var anno = Annotorious.init({
image: document.getElementyById('my-image'),
locale: 'auto',
formatter: formatter
});
You can then apply a visual style to long comments in your own CSS stylesheet.
.a9s-annotation.long {
stroke-width:4;
stroke:red;
}
Object Example
/**
* This formatter will add usernames from the annotation as a data
* attribute and apply an inline style (red outline) where multiple
* users have annotated
*/
var formatter = function(annotation) {
var contributors = [];
annotation.bodies.forEach(function(body) {
if (body.creator)
contributors.push(body.creator.id);
});
if (contributors.length > 1) {
return {
'data-users': contributors.join(', '),
'style': 'stroke-width:2; stroke: red'
}
}
}
var anno = Annotorious.init({
image: document.getElementyById('my-image'),
locale: 'auto',
formatter: formatter
});