@cogic/annotorious-openseadragon
Version:
Annotorious image annotation for OpenSeadragon
295 lines (216 loc) • 8.97 kB
JSX
import React from 'react';
import ReactDOM from 'react-dom';
import Emitter from 'tiny-emitter';
import OpenSeadragonAnnotator from './OpenSeadragonAnnotator';
import {
Selection,
WebAnnotation,
createEnvironment,
setLocale
} from '@recogito/recogito-client-core';
import '@cogic/annotorious/src/ImageAnnotator.scss';
import '@recogito/recogito-client-core/themes/default';
import './OpenSeadragonAnnotator.scss';
class OSDAnnotorious {
constructor(viewer, conf) {
const config = conf || {};
this._app = React.createRef();
this._emitter = new Emitter();
this._env = createEnvironment();
this._element = viewer.element;
// Set position to 'relative' if there's no position yet. This
// ensures that the viewer element provides the reference frame
// for the editor position.
const elPosition = window.getComputedStyle(this._element).getPropertyValue('position');
if (elPosition === 'static')
this._element.style.position = 'relative';
setLocale(config.locale, config.messages);
this.appContainerEl = document.createElement('DIV');
this._element.appendChild(this.appContainerEl);
ReactDOM.render(
<OpenSeadragonAnnotator
ref={this._app}
viewer={viewer}
wrapperEl={this._element}
config={config}
env={this._env}
onSelectionStarted={this.handleSelectionStarted}
onSelectionEnded={this.handleSelectionEnded}
onSelectionCreated={this.handleSelectionCreated}
onSelectionTargetChanged={this.handleSelectionTargetChanged}
onAnnotationCreated={this.handleAnnotationCreated}
onAnnotationSelected={this.handleAnnotationSelected}
onAnnotationUpdated={this.handleAnnotationUpdated}
onAnnotationDeleted={this.handleAnnotationDeleted}
onCancelSelected={this.handleCancelSelected}
onClickAnnotation={this.handleClickAnnotation}
onLoad={this.handleLoad}
onMouseEnterAnnotation={this.handleMouseEnterAnnotation}
onMouseLeaveAnnotation={this.handleMouseLeaveAnnotation} />, this.appContainerEl);
}
/********************/
/* External events */
/********************/
handleAnnotationCreated = (annotation, overrideId) =>
this._emitter.emit('createAnnotation', annotation.underlying, overrideId);
handleAnnotationDeleted = annotation =>
this._emitter.emit('deleteAnnotation', annotation.underlying);
handleAnnotationSelected = (annotation, elem) =>
this._emitter.emit('selectAnnotation', annotation.underlying, elem);
handleAnnotationUpdated = (annotation, previous) =>
this._emitter.emit('updateAnnotation', annotation.underlying, previous.underlying);
handleCancelSelected = annotation =>
this._emitter.emit('cancelSelected', annotation.underlying);
handleClickAnnotation = (annotation, elem) =>
this._emitter.emit('clickAnnotation', annotation.underlying, elem);
handleLoad = src =>
this._emitter.emit('load', src);
handleSelectionCreated = selection =>
this._emitter.emit('createSelection', selection.underlying);
handleSelectionStarted = pt =>
this._emitter.emit('startSelection', pt);
handleSelectionEnded = pt =>
this._emitter.emit('endSelection', pt);
handleSelectionTargetChanged = target =>
this._emitter.emit('changeSelectionTarget', target);
handleMouseEnterAnnotation = (annotation, elem) =>
this._emitter.emit('mouseEnterAnnotation', annotation.underlying, elem);
handleMouseLeaveAnnotation = (annotation, elem) =>
this._emitter.emit('mouseLeaveAnnotation', annotation.underlying, elem);
/********************/
/* External API */
/********************/
// Common shorthand for handling annotationOrId args
_wrap = annotationOrId =>
annotationOrId?.type === 'Annotation' ? new WebAnnotation(annotationOrId) : annotationOrId;
addAnnotation = annotation =>
this._app.current.addAnnotation(new WebAnnotation(annotation));
addDrawingTool = plugin =>
this._app.current.addDrawingTool(plugin);
cancelSelected = () =>
this._app.current.cancelSelected();
clearAnnotations = () =>
this.setAnnotations([]);
clearAuthInfo = () =>
this._env.user = null;
get disableEditor() {
return this._app.current.disableEditor;
}
set disableEditor(disabled) {
this._app.current.disableEditor = disabled;
}
get disableSelect() {
return this._app.current.disableSelect;
}
set disableSelect(select) {
this._app.current.disableSelect = select;
}
destroy = () =>
ReactDOM.unmountComponentAtNode(this.appContainerEl);
fitBounds = (annotationOrId, immediately) =>
this._app.current.fitBounds(this._wrap(annotationOrId), immediately);
fitBoundsWithConstraints = (annotationOrId, immediately) =>
this._app.current.fitBoundsWithConstraints(this._wrap(annotationOrId), immediately);
get formatters() {
return this._app.current.formatters || [];
}
set formatters(arg) {
if (arg) {
const formatters = Array.isArray(arg) ? arg : [ arg ];
this._app.current.formatters = formatters;
} else {
this._app.current.formatters = null;
}
}
getAnnotationById = annotationId => {
const a = this._app.current.getAnnotationById(annotationId);
return a?.underlying;
}
getAnnotations = () => {
const annotations = this._app.current.getAnnotations();
return annotations.map(a => a.underlying);
}
getAnnotationsIntersecting = annotationOrId =>
this._app.current.getAnnotationsIntersecting(this._wrap(annotationOrId));
getImageSnippetById = annotationId =>
this._app.current.getImageSnippetById(annotationId);
getSelected = () => {
const selected = this._app.current.getSelected();
return selected?.underlying;
}
getSelectedImageSnippet = () =>
this._app.current.getSelectedImageSnippet();
getCurrentDrawingTool = () => this._app.current.getCurrentDrawingTool();
getSelectedShape = () => this._app.current.getSelectedShape();
listDrawingTools = () =>
this._app.current.listDrawingTools();
hideAnnotation = (annotationOrId) =>
this._app.current.hideAnnotation(annotationOrId);
showAnnotation = (annotationOrId) =>
this._app.current.showAnnotation(annotationOrId);
loadAnnotations = url => fetch(url)
.then(response => response.json()).then(annotations => {
this.setAnnotations(annotations);
return annotations;
});
off = (event, callback) =>
this._emitter.off(event, callback);
on = (event, handler) =>
this._emitter.on(event, handler);
once = (event, handler) =>
this._emitter.once(event, handler);
panTo = (annotationOrId, immediately) =>
this._app.current.panTo(this._wrap(annotationOrId), immediately);
get readOnly() {
return this._app.current.readOnly;
}
set readOnly(readOnly) {
this._app.current.readOnly = readOnly;
}
removeAnnotation = annotationOrId =>
this._app.current.removeAnnotation(this._wrap(annotationOrId));
removeDrawingTool = id =>
this._app.current.removeDrawingTool(id);
saveSelected = () =>
this._app.current.saveSelected();
selectAnnotation = annotationOrId => {
const selected = this._app.current.selectAnnotation(this._wrap(annotationOrId));
return selected?.underlying;
}
setAnnotations = annotations => {
const safe = annotations || []; // Allow null for clearning all current annotations
const webannotations = safe.map(a => new WebAnnotation(a));
this._app.current.setAnnotations(webannotations);
}
setAuthInfo = authinfo =>
this._env.user = authinfo;
setDrawingEnabled = (enable, notSetTracking) =>
this._app.current.setDrawingEnabled(enable, notSetTracking);
setDrawingTool = shape =>
this._app.current.setDrawingTool(shape);
setServerTime = timestamp =>
this._env.setServerTime(timestamp);
setVisible = visible =>
this._app.current.setVisible(visible);
stopDrawing = () => {
this._app.current.stopDrawing();
}
updateSelected = (annotation, saveImmediately) => {
let updated = null;
if (annotation.type === 'Annotation') {
updated = new WebAnnotation(annotation);
} else if (annotation.type === 'Selection') {
updated = new Selection(annotation.target, annotation.body);
}
if (updated)
this._app.current.updateSelected(updated, saveImmediately);
}
get widgets() {
return this._app.current.widgets;
}
set widgets(widgets) {
this._app.current.widgets = widgets;
}
}
export default (viewer, config) =>
new OSDAnnotorious(viewer, config);