Merge pull request #4170 from lduarte1991/lduarte-harvardx-pr6
Annotation Tools: Removed background-color from image annotations
This commit is contained in:
@@ -25,23 +25,37 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
self = this,
|
||||
isOpenViewer = false;
|
||||
|
||||
/**
|
||||
* Sets up a call so that every time the OpenSeaDragon instance is opened
|
||||
* it triggers the annotations to be redrawn.
|
||||
*/
|
||||
this.addHandler("open", function() {
|
||||
isOpenViewer = true;
|
||||
if (typeof self.annotationInstance!='undefined')
|
||||
self.annotationInstance.refreshDisplay();
|
||||
});
|
||||
|
||||
|
||||
annotator
|
||||
//-- Finished the Annotator DOM
|
||||
/**
|
||||
* This function is called once annotator has loaded the annotations.
|
||||
* It will then wait until the OSD instance has loaded to start drawing
|
||||
* the annotations.
|
||||
* @param Array annotations list of annotations from annotator instance
|
||||
*/
|
||||
.subscribe("annotationsLoaded", function (annotations){
|
||||
if (!self.annotationInstance) {
|
||||
|
||||
//annotation instance should include the OSD item and annotator
|
||||
self.annotationInstance = new $._annotation({
|
||||
viewer: self,
|
||||
annotator: annotator,
|
||||
});
|
||||
|
||||
//this collection of items is included as an item of annotator so
|
||||
//that there is a method to communicate back and forth.
|
||||
annotator.osda = self.annotationInstance;
|
||||
//Wait until viewer is opened
|
||||
|
||||
//Because it takes a while for both OSD to open and for annotator
|
||||
//to get items from the backend, we wait until we get the "open" call
|
||||
function refreshDisplay(){
|
||||
if(!isOpenViewer){
|
||||
setTimeout(refreshDisplay,200);
|
||||
@@ -55,14 +69,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
}
|
||||
});
|
||||
};
|
||||
// INIT annotation
|
||||
|
||||
/**
|
||||
* Instance of the annotation package including OSD and Annotator
|
||||
* @constructor
|
||||
*/
|
||||
$._annotation = function(options) {
|
||||
//options
|
||||
options = options || {};
|
||||
if (!options.viewer) {
|
||||
throw new Error("A viewer must be specified.");
|
||||
}
|
||||
|
||||
|
||||
//variables
|
||||
this.viewer = options.viewer;
|
||||
this.annotator = options.annotator;
|
||||
@@ -71,12 +89,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
this.isDrawing = false; //if the user is drawing something
|
||||
this.rectPosition = undefined;
|
||||
|
||||
//Init
|
||||
this.init();
|
||||
//Init
|
||||
this.init();
|
||||
};
|
||||
|
||||
//-- Methods
|
||||
$._annotation.prototype = {
|
||||
/**
|
||||
* This function makes sure that the OSD buttons are created, that the
|
||||
* panning and zooming functionality is created and the annotation events.
|
||||
*/
|
||||
init: function(){
|
||||
var viewer = this.viewer;
|
||||
|
||||
@@ -97,77 +119,122 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//Viewer events
|
||||
var self = this;
|
||||
},
|
||||
|
||||
/**
|
||||
* This function is called when the user changed from panning/zooming mode to
|
||||
* annotation creation mode. It allows the annotator to accept the creation of
|
||||
* a new annotation.
|
||||
*/
|
||||
newAnnotation:function(){
|
||||
var annotator = this.annotator;
|
||||
|
||||
//This variable is to say the editor that we want create an image annotation
|
||||
//This variable tells editor that we want create an image annotation
|
||||
annotator.editor.OpenSeaDragon = this.viewer.id;
|
||||
|
||||
|
||||
//allows the adder to actually show up
|
||||
annotator.adder.show();
|
||||
|
||||
//takes into account the various wrappers and instances to put the shape
|
||||
//over the correct place.
|
||||
this._setOverShape(annotator.adder);
|
||||
|
||||
//Open a new annotator dialog
|
||||
annotator.onAdderClick();
|
||||
},
|
||||
|
||||
/**
|
||||
* This function simply allows the editor to pop up with the given annotation.
|
||||
* @param {Object} annotation The annotation item from the backend server.
|
||||
* @param {TinyMCEEditor} editor The item that pops up when you edit an annotation.
|
||||
*/
|
||||
editAnnotation: function(annotation,editor){
|
||||
//This will be usefull when we are going to edit an annotation.
|
||||
//Stupid check: is the annotation you're trying to edit an image?
|
||||
if (this._isOpenSeaDragon(annotation)){
|
||||
//this.hideDisplay();
|
||||
|
||||
var editor = editor || this.annotator.editor;
|
||||
|
||||
//set the editor over the range slider
|
||||
//set the editor over the highlighted element
|
||||
this._setOverShape(editor.element);
|
||||
editor.checkOrientation();
|
||||
|
||||
//This variable is to say the editor that we want create an image annotation
|
||||
//makes sure that we are making an image annotation
|
||||
editor.OpenSeaDragon = this.viewer.id;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function gets the annotations from the last annotator query and sorts
|
||||
* them and draws them onto the OpenSeaDragon instance. It also publishes
|
||||
* a notification in case the colorize the annotations.
|
||||
*/
|
||||
refreshDisplay: function(){
|
||||
var allannotations = this.annotator.plugins['Store'].annotations;
|
||||
var annotator = this.annotator;
|
||||
|
||||
//Sort by date the Array
|
||||
//Sort the annotations by date
|
||||
this._sortByDate(allannotations);
|
||||
|
||||
//remove all the overlays
|
||||
//remove all of the overlays
|
||||
this.viewer.drawer.clearOverlays();
|
||||
|
||||
for (var item in allannotations) {
|
||||
var an = allannotations[item];
|
||||
|
||||
//check if the annotation is an OpenSeaDragon annotation
|
||||
if (this._isOpenSeaDragon(an))
|
||||
this.drawRect(an);
|
||||
annotator.publish('colorizeHighlight', [an]);
|
||||
};
|
||||
if (this._isOpenSeaDragon(an)){
|
||||
this.drawRect(an);
|
||||
}
|
||||
}
|
||||
|
||||
//if the colored highlights by tags plugin it is notified to colorize
|
||||
annotator.publish('colorizeHighlight', [an]);
|
||||
},
|
||||
|
||||
/**
|
||||
* This function get notified every time we switch from panning/zooming mode onto
|
||||
* annotation creation mode.
|
||||
* @param {Event} e This is the event passed in from the OSD buttons.
|
||||
*/
|
||||
modeAnnotation:function(e){
|
||||
this._reset();
|
||||
var viewer = this.viewer;
|
||||
if (!this.isAnnotating){
|
||||
//When annotating, the cursor turns into a crosshair and there is a
|
||||
//green border around the OSD instance.
|
||||
jQuery('.openseadragon1').css('cursor', 'crosshair');
|
||||
jQuery('.openseadragon1').css('border', '2px solid rgb(51,204,102)');
|
||||
e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png");
|
||||
e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png");
|
||||
e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png");
|
||||
}else{
|
||||
//Otherwise, the cursor is a cross with four arrows to indicate movement
|
||||
jQuery('.openseadragon1').css('cursor', 'all-scroll');
|
||||
jQuery('.openseadragon1').css('border', 'inherit');
|
||||
e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png");
|
||||
e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_rest.png");
|
||||
e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png");
|
||||
}
|
||||
|
||||
//toggles the annotating flag
|
||||
this.isAnnotating = !this.isAnnotating?true:false;
|
||||
},
|
||||
|
||||
/**
|
||||
* This function takes in an annotation and draws the box indicating the area
|
||||
* that has been annotated.
|
||||
* @param {Object} an Annotation item from the list in the Annotator instance.
|
||||
*/
|
||||
drawRect:function(an){
|
||||
//Stupid check: Does this annotation actually have an area of annotation
|
||||
if (typeof an.rangePosition!='undefined'){
|
||||
//Sets up the visual aspects of the area for the user
|
||||
var span = document.createElement('span');
|
||||
var rectPosition = an.rangePosition;
|
||||
//Span
|
||||
span.className = "annotator-hl";
|
||||
span.style.border = '1px solid rgba(0,0,0,0.5)';
|
||||
span.style.border = '2px solid rgba(0,0,0,0.5)';
|
||||
span.style.background = 'rgba(0,0,0,0)';
|
||||
|
||||
//Adds listening items for the viewer and editor
|
||||
var onAnnotationMouseMove = this.__bind(this._onAnnotationMouseMove,this);
|
||||
var onAnnotationClick = this.__bind(this._onAnnotationClick,this);
|
||||
$.addEvent(span, "mousemove", onAnnotationMouseMove, true);
|
||||
@@ -175,9 +242,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
//Set the object in the div
|
||||
jQuery.data(span, 'annotation', an);
|
||||
|
||||
//Add the highlights to the annotation
|
||||
an.highlights = jQuery(span);
|
||||
|
||||
|
||||
//Sends the element created to the proper location within the OSD instance
|
||||
var olRect = new OpenSeadragon.Rect(rectPosition.left, rectPosition.top, rectPosition.width, rectPosition.height);
|
||||
return this.viewer.drawer.addOverlay({
|
||||
element: span,
|
||||
@@ -187,22 +256,38 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
}
|
||||
return false;
|
||||
},
|
||||
//Change object(this.rectPosition)the rectangle Position using div element(this.rect)
|
||||
|
||||
/**
|
||||
* This changes the variable rectPosition to the proper location based on
|
||||
* screen coordinates and OSD image coordinates.
|
||||
*/
|
||||
setRectPosition:function(){
|
||||
//Get the actual locations of the rectangle
|
||||
var left = parseInt(this.rect.style.left);
|
||||
var top = parseInt(this.rect.style.top);
|
||||
var width = parseInt(this.rect.style.left)+parseInt(this.rect.style.width);
|
||||
var height = parseInt(this.rect.style.top)+parseInt(this.rect.style.height);
|
||||
var startPoint = new $.Point(left,top);
|
||||
var endPoint = new $.Point(width,height);
|
||||
|
||||
//return the proper value of the rectangle
|
||||
this.rectPosition = {left:this._physicalToLogicalXY(startPoint).x,
|
||||
top:this._physicalToLogicalXY(startPoint).y,
|
||||
width:this._physicalToLogicalXY(endPoint).x-this._physicalToLogicalXY(startPoint).x,
|
||||
height:this._physicalToLogicalXY(endPoint).y-this._physicalToLogicalXY(startPoint).y
|
||||
};
|
||||
},
|
||||
|
||||
/* Handlers */
|
||||
_onCanvasMouseDown: function(event,seft) {
|
||||
|
||||
/**
|
||||
* When the user starts clicking this will create a rectangle that will be a
|
||||
* temporary position that is to be later scaled via dragging
|
||||
* @param {Event} event The actual action of clicking down.
|
||||
*/
|
||||
_onCanvasMouseDown: function(event) {
|
||||
|
||||
//action is ONLY performed if we are in annotation creation mode
|
||||
if (this.isAnnotating){
|
||||
var viewer = this.viewer;
|
||||
event.preventDefault();
|
||||
@@ -219,8 +304,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
var position = mouse.minus( elementPosition );
|
||||
viewer.innerTracker.setTracking(false);
|
||||
this.rect = document.createElement('div');
|
||||
this.rect.style.background = 'rgba(0,0,0,0.25)';
|
||||
this.rect.style.border = '1px solid rgba(0,0,0,0.5)';
|
||||
this.rect.style.background = 'rgba(0,0,0,0)';
|
||||
this.rect.style.border = '2px solid rgba(0,0,0,0.5)';
|
||||
this.rect.style.position = 'absolute';
|
||||
this.rect.className = 'DrawingRect';
|
||||
//set the initial position
|
||||
@@ -238,7 +323,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
viewer.canvas.appendChild(this.rect);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* When the user has clicked and is now dragging to create an annotation area,
|
||||
* the following function resizes the area selected.
|
||||
* @param {Event} event The actual action of dragging every time it is dragged.
|
||||
*/
|
||||
_onCanvasMouseMove: function(event) {
|
||||
|
||||
//of course, this only runs when we are in annotation creation mode and
|
||||
//when the user has clicked down (and is therefore drawing the rectangle)
|
||||
if (this.isAnnotating && this.isDrawing){
|
||||
var viewer = this.viewer;
|
||||
|
||||
@@ -266,7 +359,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
this._setOverShape(this.annotator.adder);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function will finish drawing the rectangle, get its current position
|
||||
* and then open up the editor to make the annotation.
|
||||
*/
|
||||
_onDocumentMouseUp: function() {
|
||||
|
||||
//Stupid check: only do it when in annotation creation mode and
|
||||
//when the user has begun making a rectangle over the annotation area
|
||||
if (this.isAnnotating && this.isDrawing){
|
||||
var viewer = this.viewer;
|
||||
|
||||
@@ -285,9 +386,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
this.annotator.editor.checkOrientation();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function will trigger the viewer to show up whenever an item is hovered
|
||||
* over and will cause the background color of the area to change a bit.
|
||||
* @param {Event} event The actual action of moving the mouse over an element.
|
||||
*/
|
||||
_onAnnotationMouseMove: function(event){
|
||||
var annotator = this.annotator;
|
||||
var elem = jQuery(event.target).parents('.annotator-hl').andSelf();
|
||||
|
||||
//if there is a opened annotation then show the new annotation mouse over
|
||||
if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){
|
||||
//hide the last open viewer
|
||||
@@ -305,8 +413,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
var maxx = l + w;
|
||||
var maxy = t + h;
|
||||
|
||||
//if the current position of the mouse is within the bounds of an area
|
||||
//change the background of that area to a light yellow to simulate
|
||||
//a hover. Otherwise, keep it translucent.
|
||||
this.style.background = (y <= maxy && y >= t) && (x <= maxx && x >= l)?
|
||||
'rgba(12, 150, 0, 0.3)':'rgba(255, 255, 10, 0.3)';
|
||||
'rgba(255, 255, 10, 0.05)':'rgba(0, 0, 0, 0)';
|
||||
|
||||
return (y <= maxy && y >= t) && (x <= maxx && x >= l)? jQuery(this).data("annotation") : null;
|
||||
});
|
||||
//show the annotation in the viewer
|
||||
@@ -314,63 +427,76 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
top:$.getMousePosition(event).y,
|
||||
left:$.getMousePosition(event).x,
|
||||
};
|
||||
//if the user is hovering over multiple annotation areas,
|
||||
//they will be stacked as usual
|
||||
if (annotations.length>0) annotator.showViewer(jQuery.makeArray(annotations), mousePosition);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function will zoom/pan the user into the bounding area of the annotation.
|
||||
* @param {Event} event The actual action of clicking down within an annotation area.
|
||||
*/
|
||||
_onAnnotationClick: function(event){
|
||||
//gets the annotation from the data stored in the element
|
||||
var an = jQuery.data(event.target, 'annotation');
|
||||
//gets the bound within the annotation data
|
||||
var bounds = typeof an.bounds!='undefined'?an.bounds:{};
|
||||
var currentBounds = this.viewer.drawer.viewport.getBounds();
|
||||
//if the area is not already panned and zoomed in to the correct area
|
||||
if (typeof bounds.x!='undefined') currentBounds.x = bounds.x;
|
||||
if (typeof bounds.y!='undefined') currentBounds.y = bounds.y;
|
||||
if (typeof bounds.width!='undefined') currentBounds.width = bounds.width;
|
||||
if (typeof bounds.height!='undefined') currentBounds.height = bounds.height;
|
||||
//change the zoom to the saved
|
||||
//change the zoom to the saved parameter
|
||||
this.viewer.drawer.viewport.fitBounds(currentBounds);
|
||||
},
|
||||
_onAnnotationMouseOut: function(event){
|
||||
var annotator = this.annotator;
|
||||
var elem = jQuery(event.target).parents('.annotator-hl').andSelf();
|
||||
//if there is a opened annotation then show the new annotation mouse over
|
||||
if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){
|
||||
/*jQuery(event.target.parentNode).find('.annotator-hl').map(function() {
|
||||
return this.style.background = 'rgba(255, 255, 10, 0.3)';
|
||||
});*/
|
||||
}
|
||||
},
|
||||
|
||||
/* Utilities */
|
||||
/**
|
||||
* This function will return an array of sorted items
|
||||
* @param {Array} annotations List of annotations from annotator instance.
|
||||
* @param {String} type Either 'asc' for ascending or 'desc' for descending
|
||||
*/
|
||||
_sortByDate: function (annotations,type){
|
||||
var type = type || 'asc'; //asc => The value [0] will be the most recent date
|
||||
annotations.sort(function(a,b){
|
||||
//gets the date from when they were last updated
|
||||
a = new Date(typeof a.updated!='undefined'?createDateFromISO8601(a.updated):'');
|
||||
b = new Date(typeof b.updated!='undefined'?createDateFromISO8601(b.updated):'');
|
||||
|
||||
//orders them based on type passed in
|
||||
if (type == 'asc')
|
||||
return b<a?-1:b>a?1:0;
|
||||
else
|
||||
return a<b?-1:a>b?1:0;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* This function creates the button that will switch back and forth between
|
||||
* annotation creation mode and panning/zooming mode.
|
||||
*/
|
||||
_createNewButton:function(){
|
||||
var viewer = this.viewer;
|
||||
var onFocusHandler = $.delegate( this, onFocus );
|
||||
var onBlurHandler = $.delegate( this, onBlur );
|
||||
var onModeAnnotationHandler = $.delegate( this, this.modeAnnotation );
|
||||
/* Buttons */
|
||||
var viewer = this.viewer;
|
||||
var self = this;
|
||||
viewer.modeAnnotation = new $.Button({
|
||||
element: viewer.modeAnnotation ? $.getElement( viewer.modeAnnotation ) : null,
|
||||
clickTimeThreshold: viewer.clickTimeThreshold,
|
||||
clickDistThreshold: viewer.clickDistThreshold,
|
||||
tooltip: "New Annotation",
|
||||
srcRest: self.resolveUrl( viewer.prefixUrl,"newan_rest.png"),
|
||||
srcGroup: self.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"),
|
||||
srcHover: self.resolveUrl( viewer.prefixUrl,"newan_hover.png"),
|
||||
srcDown: self.resolveUrl( viewer.prefixUrl,"newan_pressed.png"),
|
||||
onRelease: onModeAnnotationHandler,
|
||||
onFocus: onFocusHandler,
|
||||
onBlur: onBlurHandler
|
||||
});
|
||||
/* Buttons */
|
||||
var viewer = this.viewer;
|
||||
var self = this;
|
||||
viewer.modeAnnotation = new $.Button({
|
||||
element: viewer.modeAnnotation ? $.getElement( viewer.modeAnnotation ) : null,
|
||||
clickTimeThreshold: viewer.clickTimeThreshold,
|
||||
clickDistThreshold: viewer.clickDistThreshold,
|
||||
tooltip: "New Annotation",
|
||||
srcRest: self.resolveUrl( viewer.prefixUrl,"newan_rest.png"),
|
||||
srcGroup: self.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"),
|
||||
srcHover: self.resolveUrl( viewer.prefixUrl,"newan_hover.png"),
|
||||
srcDown: self.resolveUrl( viewer.prefixUrl,"newan_pressed.png"),
|
||||
onRelease: onModeAnnotationHandler,
|
||||
onFocus: onFocusHandler,
|
||||
onBlur: onBlurHandler
|
||||
});
|
||||
|
||||
//- Wrapper Annotation Menu
|
||||
viewer.wrapperAnnotation = new $.ButtonGroup({
|
||||
@@ -380,6 +506,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
clickTimeThreshold: viewer.clickTimeThreshold,
|
||||
clickDistThreshold: viewer.clickDistThreshold
|
||||
});
|
||||
|
||||
//area makes sure that the annotation button only appears when everyone is
|
||||
//allowed to annotate or if you are an instructor
|
||||
if(this.options.viewer.annotation_mode == "everyone" || this.options.viewer.flags){
|
||||
/* Set elements to the control menu */
|
||||
viewer.annotatorControl = viewer.wrapperAnnotation.element;
|
||||
@@ -396,14 +525,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function makes sure that if you're switching to panning/zooming mode,
|
||||
* the last rectangle you drew (but didn't save) gets destroyed.
|
||||
*/
|
||||
_reset: function(){
|
||||
//Find and remove DrawingRect. This is the previous rectangle
|
||||
this._removeElemsByClass('DrawingRect',this.viewer.canvas);
|
||||
|
||||
//Show adder and hide editor
|
||||
this.annotator.editor.element[0].style.display = 'none';
|
||||
},
|
||||
|
||||
/**
|
||||
* This function binds the function to the object it was created from
|
||||
* @param {function} fn This is the function you want to apply
|
||||
* @param {Object} me This is the object you should pass it to (usually itself)
|
||||
*/
|
||||
__bind: function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
// Remove all the elements with a given name inside "inElement"
|
||||
|
||||
/**
|
||||
* Remove all the elements with a given name inside "inElement" to maintain
|
||||
* a limited scope.
|
||||
* @param {String} className Class that should be removed
|
||||
* @param {HTMLElement} inElement Element in which classes should be removed
|
||||
*/
|
||||
_removeElemsByClass: function(className,inElement){
|
||||
var className = className || '';
|
||||
var inElement = inElement || {};
|
||||
@@ -412,24 +559,40 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
divs[i].remove();
|
||||
}
|
||||
},
|
||||
//Detect if the annotation is an image annotation
|
||||
|
||||
/**
|
||||
* Detect if the annotation is an image annotation and there's a target, open
|
||||
* OSD instance.
|
||||
* @param {Object} an Annotation from the Annotator instance
|
||||
*/
|
||||
_isOpenSeaDragon: function (an){
|
||||
var annotator = this.annotator;
|
||||
var rp = an.rangePosition;
|
||||
|
||||
//Makes sure OSD exists and that annotation is an image annotation
|
||||
//with a position in the OSD instance
|
||||
var isOpenSeaDragon = (typeof annotator.osda != 'undefined');
|
||||
var isContainer = (typeof an.target!='undefined' && an.target.container==this.viewer.id );
|
||||
var isImage = (typeof an.media!='undefined' && an.media=='image');
|
||||
var isRP = (typeof rp!='undefined');
|
||||
var isSource = false;
|
||||
//Save source url
|
||||
var source = this.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' ');
|
||||
if(isContainer) isSource = (an.target.src == compareUrl);
|
||||
|
||||
//Double checks that the image being displayed matches the annotations
|
||||
var source = this.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' ');
|
||||
if(isContainer) isSource = (an.target.src == compareUrl);
|
||||
|
||||
return (isOpenSeaDragon && isContainer && isImage && isRP && isSource);
|
||||
},
|
||||
|
||||
/* Annotator Utilities */
|
||||
/**
|
||||
* Makes sure that absolute x and y values for overlayed section are
|
||||
* calculated to match area within OSD instance
|
||||
* @param {HTMLElement} elem Element where shape is overlayed
|
||||
*/
|
||||
_setOverShape: function(elem){
|
||||
//Calculate Point absolute positions
|
||||
var rectPosition = this.rectPosition || {};
|
||||
@@ -442,7 +605,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
var positionCanvas = $.getElementPosition(this.viewer.canvas);
|
||||
var positionAdder = {};
|
||||
|
||||
//Fix with positionCanvas
|
||||
//Fix with positionCanvas based on annotator wrapper and OSD area
|
||||
startPoint = startPoint.plus(positionCanvas);
|
||||
endPoint = endPoint.plus(positionCanvas);
|
||||
|
||||
@@ -452,12 +615,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
positionAdder.top = (startPoint.y - positionAnnotator.y) + (endPoint.y - startPoint.y) / 2; //It is not necessary fix with - positionAnnotator.y
|
||||
elem.css(positionAdder);
|
||||
},
|
||||
|
||||
resolveUrl: function( prefix, url ) {
|
||||
return prefix ? prefix + url : url;
|
||||
},
|
||||
|
||||
/* Canvas Utilities */
|
||||
// return a point with the values in percentage related to the Image
|
||||
// point is an object $.Point with the value of the canvas relative coordenates
|
||||
/**
|
||||
* Given a point of x and y values in pixels it will return a point with
|
||||
* percentages in relation to the Image object
|
||||
* @param {$.Point} point Canvas relative coordinates in pixels
|
||||
* @return {$.Point} Returns Image relative percentages
|
||||
*/
|
||||
_physicalToLogicalXY: function(point){
|
||||
var point = typeof point!='undefined'?point:{};
|
||||
var boundX = this.viewer.viewport.getBounds(true).x;
|
||||
@@ -472,8 +641,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
y = boundY + ((y / containerSizeY) * boundHeight);
|
||||
return new $.Point(x,y);
|
||||
},
|
||||
// return a point with the values in pixels related to the canvas element
|
||||
// point is an object $.Point with the value of the Image relative percentage
|
||||
|
||||
/**
|
||||
* Given values in percentage relatives to the image it will return a point in
|
||||
* pixels related to the canvas element.
|
||||
* @param {$.Point} point Image relative percentages
|
||||
* @return {$.Point} Returns canvas relative coordinates in pixels
|
||||
*/
|
||||
_logicalToPhysicalXY: function(point){
|
||||
var point = typeof point!='undefined'?point:{};
|
||||
var boundX = this.viewer.viewport.getBounds(true).x;
|
||||
@@ -491,7 +665,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
}
|
||||
|
||||
/* General functions */
|
||||
//initiates an animation to hide the controls
|
||||
/**
|
||||
* initiates an animation to hide the controls
|
||||
*/
|
||||
function beginControlsAutoHide( viewer ) {
|
||||
if ( !viewer.autoHideControls ) {
|
||||
return;
|
||||
@@ -505,7 +681,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
scheduleControlsFade( viewer );
|
||||
}, viewer.controlsFadeDelay );
|
||||
}
|
||||
//stop the fade animation on the controls and show them
|
||||
/**
|
||||
* stop the fade animation on the controls and show them
|
||||
*/
|
||||
function abortControlsAutoHide( viewer ) {
|
||||
var i;
|
||||
viewer.controlsShouldFade = false;
|
||||
@@ -531,19 +709,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
Annotator.Plugin.OpenSeaDragon = (function(_super) {
|
||||
__extends(OpenSeaDragon, _super);
|
||||
|
||||
//constructor
|
||||
/**
|
||||
* Creates an instance of the plugin that interacts with OpenSeaDragon.
|
||||
* @constructor
|
||||
*/
|
||||
function OpenSeaDragon() {
|
||||
this.pluginSubmit = __bind(this.pluginSubmit, this);
|
||||
_ref = OpenSeaDragon.__super__.constructor.apply(this, arguments);
|
||||
|
||||
//To facilitate calling items, we want to be able to get the index of a value
|
||||
this.__indexOf = [].indexOf;
|
||||
if(!this.__indexOf){
|
||||
this.__indexOf = function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (i in this && this[i] === item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Basically you iterate through every item on the list, if it matches
|
||||
//the item you are looking for return the current index, otherwise return -1
|
||||
this.__indexOf = function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (i in this && this[i] === item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
return _ref;
|
||||
@@ -551,7 +737,11 @@ Annotator.Plugin.OpenSeaDragon = (function(_super) {
|
||||
|
||||
OpenSeaDragon.prototype.field = null;
|
||||
OpenSeaDragon.prototype.input = null;
|
||||
|
||||
|
||||
/**
|
||||
* This function initiates the editor that will apear when you edit/create an
|
||||
* annotation and the viewer that appears when you hover over an item.
|
||||
*/
|
||||
OpenSeaDragon.prototype.pluginInit = function() {
|
||||
//Check that annotator is working
|
||||
if (!Annotator.supported()) {
|
||||
@@ -578,51 +768,59 @@ Annotator.Plugin.OpenSeaDragon = (function(_super) {
|
||||
return this.input = $(this.field).find(':input');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// New JSON for the database
|
||||
/**
|
||||
* This function is called by annotator whenever user hits the "Save" Button. It will
|
||||
* first check to see if the user is editing or creating and then save the
|
||||
* metadata for the image in an object that will be passed to the backend.
|
||||
*/
|
||||
OpenSeaDragon.prototype.pluginSubmit = function(field, annotation) {
|
||||
//Select the new JSON for the Object to save
|
||||
if (this.EditOpenSeaDragonAn()){
|
||||
var annotator = this.annotator;
|
||||
var osda = annotator.osda;
|
||||
var position = osda.rectPosition;
|
||||
var position = osda.rectPosition || {};
|
||||
var isNew = typeof annotation.media=='undefined';
|
||||
if (typeof annotation.media == 'undefined') annotation.media = "image"; // - media
|
||||
annotation.target = annotation.target || {}; // - target
|
||||
annotation.target.container = osda.viewer.id || ""; // - target.container
|
||||
//Save source url
|
||||
var source = osda.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
annotation.target.src = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); // - target.src (media source)
|
||||
annotation.target.ext = source.fileFormat || ""; // - target.ext (extension)
|
||||
annotation.bounds = osda.viewer.drawer.viewport.getBounds() || {}; // - bounds
|
||||
|
||||
var finalimagelink = source["@id"].replace("/info.json", "");
|
||||
var highlightX = Math.round(position.left * source["width"]);
|
||||
var highlightY = Math.round(position.top * source["width"]);
|
||||
var highlightWidth = Math.round(position.width * source["width"]);
|
||||
var highlightHeight = Math.round(position.height * source["width"]);
|
||||
annotation.target.thumb = finalimagelink + "/" + highlightX + "," + highlightY + "," + highlightWidth + "," + highlightHeight + "/full/0/native." + source["formats"][0];
|
||||
if(isNew) annotation.rangePosition = position || {}; // - rangePosition
|
||||
annotation.updated = new Date().toISOString(); // - updated
|
||||
if (typeof annotation.created == 'undefined')
|
||||
annotation.created = annotation.updated; // - created
|
||||
}else{
|
||||
if (typeof annotation.media == 'undefined')
|
||||
annotation.media = "text"; // - media
|
||||
annotation.updated = new Date().toISOString(); // - updated
|
||||
if (typeof annotation.created == 'undefined')
|
||||
annotation.created = annotation.updated; // - created
|
||||
if(isNew){
|
||||
//if it's undefined, we know it's an image because the editor within
|
||||
//the OSD instance was open
|
||||
if (typeof annotation.media == 'undefined') annotation.media = "image"; // - media
|
||||
annotation.target = annotation.target || {}; // - target
|
||||
annotation.target.container = osda.viewer.id || ""; // - target.container
|
||||
|
||||
//Save source url
|
||||
var source = osda.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
annotation.target.src = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); // - target.src (media source)
|
||||
annotation.target.ext = source.fileFormat || ""; // - target.ext (extension)
|
||||
|
||||
//Gets the bounds in order to save them for zooming in and highlight properties
|
||||
annotation.bounds = osda.viewer.drawer.viewport.getBounds() || {}; // - bounds
|
||||
var finalimagelink = source["@id"].replace("/info.json", "");
|
||||
var highlightX = Math.round(position.left * source["width"]);
|
||||
var highlightY = Math.round(position.top * source["width"]);
|
||||
var highlightWidth = Math.round(position.width * source["width"]);
|
||||
var highlightHeight = Math.round(position.height * source["width"]);
|
||||
|
||||
//creates a link to the OSD server that contains the image to get
|
||||
//the thumbnail of the selected portion of the image
|
||||
annotation.target.thumb = finalimagelink + "/" + highlightX + "," + highlightY + "," + highlightWidth + "," + highlightHeight + "/full/0/native." + source["formats"][0];
|
||||
if(isNew) annotation.rangePosition = position || {}; // - rangePosition
|
||||
|
||||
//updates the dates associated with creation and update
|
||||
annotation.updated = new Date().toISOString(); // - updated
|
||||
if (typeof annotation.created == 'undefined')
|
||||
annotation.created = annotation.updated; // - created
|
||||
}
|
||||
}
|
||||
return annotation.media;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------ Methods ------//
|
||||
//Detect if we are creating or editing an OpenSeaDragon annotation
|
||||
/**
|
||||
* Detect if we are creating or editing an OpenSeaDragon annotation
|
||||
*/
|
||||
OpenSeaDragon.prototype.EditOpenSeaDragonAn = function (){
|
||||
var wrapper = $('.annotator-wrapper').parent()[0],
|
||||
annotator = window.annotator = $.data(wrapper, 'annotator'),
|
||||
@@ -631,31 +829,45 @@ Annotator.Plugin.OpenSeaDragon = (function(_super) {
|
||||
return (isOpenSeaDragon && typeof OpenSeaDragon!='undefined' && OpenSeaDragon!==-1);
|
||||
};
|
||||
|
||||
//Detect if the annotation is an OpenSeaDragon annotation
|
||||
/**
|
||||
* Detect if the annotation is an image annotation and there's a target, open
|
||||
* OSD instance.
|
||||
* @param {Object} an Annotation from the Annotator instance
|
||||
*/
|
||||
OpenSeaDragon.prototype.isOpenSeaDragon = function (an){
|
||||
var wrapper = $('.annotator-wrapper').parent()[0];
|
||||
var annotator = window.annotator = $.data(wrapper, 'annotator');
|
||||
var rp = an.rangePosition;
|
||||
var isOpenSeaDragon = (typeof annotator.osda != 'undefined');
|
||||
var isContainer = (typeof an.target!='undefined' && an.target.container==annotator.osda.viewer.id );
|
||||
var isImage = (typeof an.media!='undefined' && an.media=='image');
|
||||
var isRP = (typeof rp!='undefined');
|
||||
var isSource = false;
|
||||
//Save source url
|
||||
var source = annotator.osda.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' ');
|
||||
if(isContainer) isSource = (an.target.src == compareUrl);
|
||||
return (isOpenSeaDragon && isContainer && isImage && isRP && isSource);
|
||||
var annotator = this.annotator;
|
||||
var rp = an.rangePosition;
|
||||
|
||||
//Makes sure OSD exists and that annotation is an image annotation
|
||||
//with a position in the OSD instance
|
||||
var isOpenSeaDragon = (typeof annotator.osda != 'undefined');
|
||||
var isContainer = (typeof an.target!='undefined' && an.target.container==this.viewer.id );
|
||||
var isImage = (typeof an.media!='undefined' && an.media=='image');
|
||||
var isRP = (typeof rp!='undefined');
|
||||
var isSource = false;
|
||||
|
||||
//Double checks that the image being displayed matches the annotations
|
||||
var source = this.viewer.source;
|
||||
var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'';
|
||||
var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'';
|
||||
var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' ');
|
||||
if(isContainer) isSource = (an.target.src == compareUrl);
|
||||
|
||||
return (isOpenSeaDragon && isContainer && isImage && isRP && isSource);
|
||||
};
|
||||
|
||||
//Delete OpenSeaDragon Annotation
|
||||
/**
|
||||
* Deletes the OSD annotation from Annotator and refreshes display to remove element
|
||||
* @param {Object} an Annotation object from the Annotator instance
|
||||
*/
|
||||
OpenSeaDragon.prototype._deleteAnnotation = function(an){
|
||||
//Remove the annotation of the plugin Store
|
||||
var annotations = this.annotator.plugins['Store'].annotations;
|
||||
|
||||
//Failsafe in case annotation is not immediately removed from annotations list
|
||||
if (annotations.indexOf(an)>-1)
|
||||
annotations.splice(annotations.indexOf(an), 1);
|
||||
|
||||
//Refresh the annotations in the display
|
||||
this.annotator.osda.refreshDisplay();
|
||||
};
|
||||
@@ -691,7 +903,7 @@ Annotator.Plugin.OpenSeaDragon = (function(_super) {
|
||||
//-- Viewer
|
||||
function hideViewer(){
|
||||
jQuery(annotator.osda.viewer.canvas.parentNode).find('.annotator-hl').map(function() {
|
||||
return this.style.background = 'rgba(255, 255, 10, 0.3)';
|
||||
return this.style.background = 'rgba(0, 0, 0, 0)';
|
||||
});
|
||||
annotator.viewer.unsubscribe("hide", hideViewer);
|
||||
};
|
||||
|
||||
53
common/static/js/vendor/ova/catch/js/catch.js
vendored
53
common/static/js/vendor/ova/catch/js/catch.js
vendored
@@ -614,36 +614,49 @@ CatchAnnotation.prototype = {
|
||||
tot = typeof annotations !='undefined'?annotations.length:0,
|
||||
attempts = 0; // max 100
|
||||
if(annotation.media == "image"){
|
||||
self.refreshCatch(true);
|
||||
self.checkTotAnnotations();
|
||||
self.refreshCatch(true);
|
||||
self.checkTotAnnotations();
|
||||
} else {
|
||||
//This is to watch the annotations object, to see when is deleted the annotation
|
||||
var ischanged = function(){
|
||||
var new_tot = annotator.plugins['Store'].annotations.length;
|
||||
if (attempts<100)
|
||||
setTimeout(function(){
|
||||
if (new_tot != tot){
|
||||
self.refreshCatch(true);
|
||||
self.checkTotAnnotations();
|
||||
}else{
|
||||
attempts++;
|
||||
ischanged();
|
||||
}
|
||||
},100); //wait for the change in the annotations
|
||||
};
|
||||
ischanged();
|
||||
var ischanged = function(){
|
||||
var new_tot = annotator.plugins['Store'].annotations.length;
|
||||
if (attempts<100)
|
||||
setTimeout(function(){
|
||||
if (new_tot != tot){
|
||||
self.refreshCatch(true);
|
||||
self.checkTotAnnotations();
|
||||
}else{
|
||||
attempts++;
|
||||
ischanged();
|
||||
}
|
||||
},100); //wait for the change in the annotations
|
||||
};
|
||||
ischanged();
|
||||
}
|
||||
});
|
||||
annotator.subscribe("annotationCreated", function (annotation){
|
||||
var attempts = 0; // max 100
|
||||
//wait to get an annotation id
|
||||
//There is a delay between calls to the backend--especially reading after
|
||||
//writing. This function listens to when a function is created and waits
|
||||
//until the server provides it with an annotation id before doing anything
|
||||
//with it.
|
||||
var ischanged = function(){
|
||||
if (attempts<100)
|
||||
setTimeout(function(){
|
||||
if (typeof annotation.id!='undefined'){
|
||||
|
||||
//once it gets the annotation id, the table refreshes to show
|
||||
//the edits
|
||||
self.refreshCatch();
|
||||
if (typeof annotation.parent != 'undefined' && annotation.parent != '0'){
|
||||
|
||||
//if annotation made was actually a replay to an annotation
|
||||
//i.e. the only difference is that annotations that are
|
||||
//not replies have no "parent"
|
||||
var replies = $("[annotationid="+annotation.parent+"]").find(".controlReplies .hideReplies");
|
||||
|
||||
//forces "Show replies" section to show and then refreshes
|
||||
//via two clicks
|
||||
replies.show();
|
||||
replies.click();
|
||||
replies.click();
|
||||
@@ -826,6 +839,9 @@ CatchAnnotation.prototype = {
|
||||
}
|
||||
for(var item in allannotations){
|
||||
var an = allannotations[item];
|
||||
//Makes sure that all images are set to transparent in case one was
|
||||
//previously selected.
|
||||
an.highlights[0].style.background = "rgba(0,0,0,0)";
|
||||
if (typeof an.id!='undefined' && an.id == osdaId){//this is the annotation
|
||||
var bounds = new OpenSeadragon.Rect(an.bounds.x, an.bounds.y, an.bounds.width, an.bounds.height);
|
||||
osda.viewer.viewport.fitBounds(bounds, false);
|
||||
@@ -833,6 +849,9 @@ CatchAnnotation.prototype = {
|
||||
console.log(an.target.container);
|
||||
$('html,body').animate({scrollTop: $("#"+an.target.container).offset().top},
|
||||
'slow');
|
||||
//signifies a selected annotation once OSD has zoomed in on the
|
||||
//appropriate area, it turns the background a bit yellow
|
||||
an.highlights[0].style.background = "rgba(255,255,10,0.2)";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user