Annotating An Image In JavaScript – Annotorious

Category: Image , Javascript , Recommended | October 9, 2021
Author:recogito
Views Total:63 views
Official Page:Go to website
Last Update:October 9, 2021
License:BSD-3-Clause

Preview:

Annotating An Image In JavaScript – Annotorious

Description:

Annotorious is a simple yet feature-rich JavaScript image annotation library that adds custom comments, notes, tags to a specific part of an image.

Features:

  • Load pre-defined annotations from a JSON file.
  • Drag and drop to create new annotations from an editor popup.
  • Based on W3C WebAnnotation model.
  • Touch & Mobile friendly.

How to use it:

1. Install and import the Annotorious as a module.

# NPM
$ npm install @recogito/annotorious --save
import { Annotorious } from '@recogito/annotorious';

2. Or download the package and insert the annotorious.min.js into the HTML document.

<link rel="annotorious.min.css" href="styles.css" />
<script src="annotorious.min.js"></script>

3. Initialize the Annotorious on the image and we’re ready to go.

<img id="example" src="example.jpg" />
var anno = Annotorious.init({
    image: 'example'
});

4. Define your annotations in a w3c.json file and load it on page load.

// annotations.w3c.json
[
  { 
    "@context": "http://www.w3.org/ns/anno.jsonld",
    "id": "#unique-ID-Here",
    "type": "Annotation",
    "body": [{
      "type": "TextualBody",
      "value": "Comments Here"
    }, {
      "type": "TextualBody",
      "purpose": "tagging",
      "value": "Tag 1"
    }, {
      "type": "TextualBody",
      "purpose": "tagging",
      "value": "Tag 2"
    }],
    "target": {
      "selector": [{
        "type": "FragmentSelector",
        "conformsTo": "http://www.w3.org/TR/media-frags/",
        "value": "xywh=pixel:270,120,90,170"
      }]
    }
  }
]
anno.loadAnnotations('annotations.w3c.json');

3. Enable read-only mode. Defaults to false.

var anno = Annotorious.init({
    image: 'example',
    readOnly: true
});

4. Disable the editor popup. Defaults to false.

var anno = Annotorious.init({
    image: 'example',
    disableEditor: true
});

5. Add a new annotation to the image following the structure you’ve seen in the annotations.w3c.json.

// add an annotation
anno.addAnnotation(annotation [, readOnly]);

// add an array of annotations
anno.setAnnotations(annotations);

6. Remove an annotation from the image.

anno.removeAnnotation(ID);

7. Get all annotations.

anno.getAnnotations();

8. Select an annotation.

// select the current annotation
anno.selectAnnotation();

// select a specific annotation
anno.selectAnnotation(ID);

9. Show/hide the annotations.

anno.setAnnotationsVisible(TRUE/FALSE);

10. Apply a custom template to the annotation.

anno.applyTemplate(template, openEditor[TRUE/FALSE]);

11. Set & get author info.

// set
anno.setAuthInfo({
  id: 'https://cssscript.com',
  displayName: 'CSSScript'
});
// clear
anno.clearAuthInfo();

12. Switch between drawing tools: ‘rect’ or ‘polygon’.

anno.setDrawingTool(toolName);

13. Show or hide the annotation layer.

anno.setAnnotationsVisible(boolean);

14. Set a server time timestamp.

anno.setServerTime(timestamp);

15. Destroy the instance.

anno.destroy();

16. Event handlers.

anno.on('changeSelectionTarget', function(target) {
  // when the shape of a newly created selection
});

anno.on('createSelection', function(selection) {
  // when a new selection shape is drawn on the image
});

anno.on('cancelSelection', function(selection) {
  // do something
});

anno.on('selectAnnotation', function(annotation) {
  console.log('selected', annotation);
});

anno.on('createAnnotation', function(a) {
  console.log('created', a);
});

anno.on('updateAnnotation', function(annotation, previous) {
  console.log('updated', previous, 'with', annotation);
});

anno.on('deleteAnnotation', function(annotation) {
  console.log('deleted', annotation);
});

anno.on('mouseEnterAnnotation', function(annotation, event) {
  console.log('mouseEnter', annotation);
});

anno.on('mouseLeaveAnnotation', function(annotation, event) {
  console.log('mouseLeave', annotation);
});

17. Use custom formater function:

// String Example
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({
    formatter: formatter
});
// Object Example
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({
    formatter: formatter
});

Changelog:

v2.5.7 (10/09/2021)

  • Added a mechanism for widget plugins to use built-in I18N features and register their own localized UI labels
  • New event changeSelected that fires when the user changes the selection by clicking an annotation while another annotation is currently selected.
  • The editor now adjusts position when widgets are changing. This is to avoid mis-placement when the editor grows/shrinks
  • Draggable surfaces on the editor are now properly indicated with cursor move icon
  • Cosmetic tweak: in cases where the editor is pushed from its original position to remain in the view, the litte arrow now hides. This is to avoid the arrow pointing outside of the annotation.
  • Bugfixes

v2.5.6 (09/27/2021)

  • Crude support for displaying “point selectors” (Fragment selectors with zero width and height)
  • Bugfixes When importing via script-tag, source map file now loads properly

v2.5.5 (09/19/2021)

  • Added Finnish and Korean UI labels
  • Added support for percent-encoded Media Fragment selectors. (Annotorious will read both pixel and percent-encoded fragments. When new rectangle annotations are created, the fragmentUnit init parameter determines their encoding. Set fragementUnit: ‘percent’ to write percent-encoded annotations, or fragmentUnit: ‘pixel’ (default) to write pixel-encoded annotations.
  • Added support for tagging vocabularies with ontology terms, where each vocabulary item consists of a label and a URI.
  • Widget API: saveImmediately and onUpsertBody methods now properly exposed to VanillaJS widgets
  • Fixed a bug that caused broken editor offset in Firefox when using the Shape Labels plugin

v2.5.4 (08/17/2021)

  • disableSelect is now an init option
  • wigets can now a getter/setter option
  • anno.getSelected now returns live editor state
  • Minor behavior fixes to draggable editor behavior

v2.5.3 (08/11/2021)

  • Minor changes to the tool plugin API

v2.5.2 (08/07/2021)

  • Added French UI labels
  • Behavior improvements/fixes

v2.5.1 (07/15/2021)

  • New property disableSelect to temporarily disable all selection functionality
  • New event clickAnnotation
  • Added .once method for registering a one-time event handler

v2.5.0 (07/08/2021)

  • New crosshair feature that can optionally replace the mouse cursor, for more precise selection. Enable via a crosshair:true init option
  • New .setWidgets API method that allows changing editor widget configuration at runtime
  • Behavior improvements/fixes
  • Updated Editor plugin API
  • Separation of IE support reduces the core bundle size by 76kB

v2.4.4 (06/22/2021)

  • Fixes a bug that caused resize handes to be offset on Safari for responsive images, and on the OpenSeadragon plugin

v2.4.2 (06/21/2021)

  • Detachable editor: it’s now possible to grab and drag the editor away from the annotation with mouse or touch, e.g. to avoid the editor getting in the way of shape resizing. The editor stays detached until closed.
  • Internal changes to the plugin API to support drawing tools for different shape types

v2.4.1 (06/13/2021)

  • New startSelection event fired when the user starts drawing a shape
  • Editor now supports widgets built with Preact, and no longer breaks for widgets using React hooks
  • Bugfixes

v2.4.0 (05/22/2021)

  • New init option handleRadius, for setting the radius of the resize handles
  • New init option messages to override UI labels when initializing
  • Escape key now cancels editing
  • Formatters now support insertion of DOM elements into the annotation SVG group
  • Added support for React editor widgets
  • Improved auto-positioning of the editor, so that it now remains inside the viewport in (almost) all situations
  • Shapes are now constrained to the image area (when editing a shape, it’s no longer possible to push it outside the image)
  • When resizing a rectangle selection, it is now possible to move the dragged handle into neighbour quadrants without creating a zero-size rectangle
  • anno.cancelSelected() now stops drawing if a tool is currently active
  • Fixed broken .clearAnnotations() method
  • Fixed polygon area computation – larger polygons no longer cover smaller rectangles
  • Fixed polygon serialization syntax, which was working in most browser, but technically not compliant to the SVG spec
  • Calling destroy while a shape is selected no longer causes an error
  • Calling setDrawingTool in read-only mode no longer causes an error
  • Calling setVisible(false) now properly deselects the selected annotation
  • Removed axios dependency in .loadAnnotations in favor of standard fetch API, reducing uncompressed download size by ~12kB
  • SVG selectors now go through basic security sanitization: <script> tags and on… event handlers are removed
  • Added most recently available dependency security patches

v2.3.3 (03/30/2021)

  • Fixed a bug that caused polygons to close in touch mode after ~500ms of idleness, even if the finger wasn’t on the screen (intended behavior is tap-and-hold for ~500ms)
  • Touch mode now works properly on images in scrolled pages
  • Bugfix: when creating a new selection, attempting to modify the shape caused a ‘cancel’. Newly created shapes can now be modified immediately
  • Editor now (finally) auto-positions correctly when moving it outside the browser viewport
  • When allowing empty annotations (allowEmpty: true config option), empty annotations get a delete button

v2.3.2 (03/30/2021)

  • Adds CSS fixes to the style of the tag widget
  • Bugfix: calling .selectAnnotation triggered two selectAnnotation events, when it should trigger any at all – fixed
  • Regression bug fix: resize handles now scale properly again on responsive images
  • Fixed a bug that caused coordinates to shift when annotating images on scrolled-down on touch devices
  • Fixed various minor behavior bugs in touch mode
  • Upgrades some security-patched npm dependencies

v2.3.1 (03/29/2021)

  • Minor behavior tweaks to headless mode.
  • When creating annotations in headless mode that have no bodies, annotations are immediately removed (as they should be), unless the allowEmpty config option is set to true.
  • When changing the drawing tool, the current drawing tool is properly stopped in case drawing is currently ongoing.

v2.3.0 (03/28/2021)

  • Bugfix: .removeAnnotation now allows annotation object or annotation ID as argument
  • Delete Annotation button (finally!), with a mechanism that allows widget plugins to control whether delete is possible or not
  • headless config option now deprecated. Use disableEditor instead
  • disableEditor can be changed without re-initializing Annotorious
  • ReadOnly mode can now be changed without re-initializing Annotorious, through the .readOnly property
  • allowEmpty config option
  • Tweaked touch interaction: both press+hold and move+hold are now translated to double click, which closes the polygon
  • Removed Hammer.js dependency

v2.2.5 (03/17/2021)

  • Switched to Terser for code optimization, due to ongoing security issues with Uglify
  • Fixed errors in the event lifecycle
  • Size-based sorting of polygon shapes, so that large polygon annotations no longer obstruct smaller polygon shapes
  • Internal API changes to enable more powerful plugins
  • Reduced code redundancy in drawing tool implementations
  • .listDrawingTools API method

v2.2.4 (03/11/2021)

  • Fixes a bug that caused .getAnnotations API method to break when called from inside an event handler
  • Adds cancelSelected event when user cancels editing a selection

v2.2.3 (03/10/2021)

  • Fixed cancelSelected event

v2.2.2 (02/28/2021)

  • Fixes a bug that caused wrong editor position when the window is scrolled horizontally
  • Adds support for touch devices

v2.2.1 (02/15/2021)

  • Bugfixes
  • Shape edit handles can now be resized via CSS transform: scale(…)
  • Shape editing now works properly in headless mode
  • Editor: Fixed a minor bug concerning proper display of created/lastModified times; Greek UI language translation
  • Widget API: Widgets now get an updated annotation instance when the user changes the selection target (e.g. move/resize in Annotorious); Added .onSetProperty method that allows widgets to attach top-level props the annotation

v2.2.0 (01/03/2021)

  • Added Dutch UI translation
  • New API method clearAnnotations
  • Added cancelSelection event, when user hits ‘cancel’ on a newly created shape
  • Revised headless API
  • New API method saveSelected to save changes to an annotation programmatically
  • New API method cancelSelected to cancel programmatically
  • Removed support for applyTemplate API function in favor of new headless API. Example: to apply a tag automatically in headless mode

v2.1.7 (12/27/2020)

  • Editor bugfixes
  • Added getSelectedImageSnippet API method

v2.1.6 (12/20/2020)

  • Bugfixes
  • Preparations/compatibility plumbing for editable shapes in OpenSeadragon

v2.1.5 (11/30/2020)

  • Fixes a regression bug that broke shape editing in v2.1.4

v2.1.4 (11/30/2020)

  • UI/behavior: clicking outside the selected shape cancels editing and closes the editor
  • Proper handling of multi-line comments in the Comment Widget
  • Localized text labels for time expressions (“2 minutes ago”), when using authInfo
  • Added missing Spanish labels for ‘Edit’ and ‘Delete’

v2.1.3 (10/14/2020)

  • Dim mask now also available for the polygon drawing tool
  • Czech UI translation
  • Tag widget: fixed broken autosuggest behavior
  • Editor plugins: config params are now properly forwarded to plugin args

v2.1.2 (09/22/2020)

  • Environment is no longer a global object, meaning that it is now safe to use multiple Recogito/Annotorious instances on the same page
  • All CSS classes are now properly prefixed to avoid clashes with other styles on the page (either with a9s for Annotorious-specific elements or r6o for elements imported from Recogito core
  • Small bugfixes to the dim mask

v2.1.1 (09/20/2020)

  • CSS styles are no longer embedded in the JavaScript file, but now have to be imported separately.
  • Editor widgets are becoming more flexible. This release is the first to include beta support for a plugin API. As a consequence, this version introduces a minimal change to how the tag widget is configured with a controlled vocabulary.

v2.0.8 (09/13/2020)

  • Minor bugfix

v2.0.7 (08/29/2020)

  • IE11 support bugfixes

v2.0.6 (08/29/2020)

  • IE11 compatibility
  • Editable polygon shapes
  • Bugfixes concerning the behavior of the tag autosuggest component
  • Security fixes for library dependencies

v2.0.5 (07/12/2020)

  • Added babel polyfill (IE11 compat)

v2.0.4 (07/12/2020)

  • Beta support for rendering any SVG shape contained in W3C Web Annotations
  • Beta support for polygon drawing
  • Various bugfixes
  • Portuguese UI translation
  • Tag widget: controlled vocabulary autosuggest
  • Selecting an annotation now adds a selected CSS class

v2.0.3 (06/12/2020)

  • Various smaller bugfixes
  • Microsoft Edge compatibility
  • Experimental support for responsive images
  • Web Annotation standard compliance: target now includes a source property with the image source URL
  • Minor API changes: selectAnnotation method now returns selected annotation object and does not fire the selectAnnotation event
  • Added support for internationalization
  • Ability to handle user information for UI display and when creating/updating annotations
  • Ability to add created and modified timestamps, with an option for the host application to sync with the server time

v2.0.2 (05/21/2020)

  • Minor bugfixes
  • Enabling readOnly annotations

v2.0.2 (05/21/2020)

  • Minor bugfixes

You Might Be Interested In:


One thought on “Annotating An Image In JavaScript – Annotorious

Leave a Reply