Skip to content
Snippets Groups Projects
Select Git revision
  • aff24731970ccd7d4cf0a5e5990dce2cf0bce2e8
  • mui5-annotation-on-video-stable default
  • get_setter_canvasSizeInformations
  • fix-error-div-into-p
  • annotation-on-video-v2
  • detached
  • annotation-on-video-r17
  • mui5
  • mui5-react-18
  • jacob-test
  • annotation-on-video protected
  • master
  • test-antoinev1
  • 20-fetch-thumbnail-on-annotation
  • add-research-field
  • Save
  • add-plugin
  • 14-wip-no-seek-to
  • 14-bug-on-video-time-control
  • 9_wip_videotests
  • _upgrade_material_ui
  • latest-tetras-16
  • v3.3.0
  • v3.2.0
  • v3.1.1
  • v3.1.0
  • v3.0.0
  • v3.0.0-rc.7
  • v3.0.0-rc.6
  • v3.0.0-rc.5
  • v3.0.0-rc.4
  • v3.0.0-rc.3
  • v3.0.0-rc.2
  • v3.0.0-rc.1
  • v3.0.0-beta.10
  • v3.0.0-beta.9
  • v3.0.0-beta.8
  • v3.0.0-beta.7
  • v3.0.0-beta.6
  • v3.0.0-beta.5
  • v3.0.0-beta.3
41 results

osd-region-draw-tool.js

Blame
  • user avatar
    Glen Robson authored
    537024fe
    History
    osd-region-draw-tool.js 11.48 KiB
    (function($) {
      $.OsdRegionDrawTool = function(options) {
        jQuery.extend(this, {
          osdViewer: null,
          parent: null,
          osd: null,
          list: null,
          annotationsToShapesMap: {},
          eventEmitter: null
        }, options);
    
        this.eventsSubscriptions = [];
    
        this.init();
      };
    
      $.OsdRegionDrawTool.prototype = {
    
        init: function() {
          this.svgOverlay = this.osdViewer.svgOverlay(this.osdViewer.id, this.windowId, this.state, this.eventEmitter);
          this.svgOverlay.show();
          this.svgOverlay.disable();
    
          this.horizontallyFlipped = false;
    
          this.listenForActions();
        },
    
        enterDisplayAnnotations: function() {
          this.svgOverlay.setMouseTool();
    
          // if a user selected the pointer mode but is still actively
          // working on an annotation, don't re-render
          if (!this.svgOverlay.inEditOrCreateMode) {
            this.exitEditMode(true);
            this.render();
          } else {
            this.svgOverlay.checkToRemoveFocus();
          }
        },
    
        enterCreateAnnotation: function() {
          // if a user selected went from pointer to a shape but is still actively
          // working on an annotation, don't re-render
          if (!this.svgOverlay.inEditOrCreateMode) {
            this.osdViewer.setMouseNavEnabled(false);
            this.svgOverlay.show();
            this.svgOverlay.enable();
            this.render();
          } else {
            this.svgOverlay.checkToRemoveFocus();
          }
        },
    
        enterCreateShape: function() {
          if (!this.svgOverlay.inEditOrCreateMode) {
            this.osdViewer.setMouseNavEnabled(false);
            this.svgOverlay.show();
            this.svgOverlay.enable();
          } else {
            this.svgOverlay.checkToRemoveFocus();
          }
        },
    
        enterEditAnnotation: function() {
          this.osdViewer.setMouseNavEnabled(false);
          this.svgOverlay.show();
          this.svgOverlay.enableEdit();
        },
    
        enterDefault: function() {
          // Removing the Tool explicitly because otherwise mouse events keep
          // firing in default mode where they shouldn't.
          this.svgOverlay.removeMouseTool();
    
          this.exitEditMode(false);
        },
    
        exitEditMode: function(showAnnotations) {
          this.osdViewer.setMouseNavEnabled(true);
          this.svgOverlay.disable();
          if (showAnnotations) {
            this.svgOverlay.show();
          } else {
            this.svgOverlay.hide();
          }
        },
    
        render: function () {
          if(this.parent.mode !== $.AnnotationsLayer.DISPLAY_ANNOTATIONS){
            return ;
          }
          this.svgOverlay.restoreEditedShapes();
          this.svgOverlay.paperScope.activate();
          this.svgOverlay.paperScope.project.clear();
          var _this = this;
          _this.annotationsToShapesMap = {};
          var strategies = [
            new $.Mirador21Strategy(),
            new $.LegacyOpenAnnotationStrategy(),
            new $.MiradorLegacyStrategy(),
            new $.MiradorDualStrategy()
          ];
    
          for (var i = 0; i < this.list.length; i++) {
            var annotation = this.list[i];
            try {
              var shapeArray = this.prepareShapeArray(annotation, strategies);
              if (shapeArray.length > 0) {
                _this.svgOverlay.restoreLastView(shapeArray);
                _this.annotationsToShapesMap[annotation['@id']] = shapeArray;
              } else {
                console.log("ERROR couldn't find a strategy for " + annotation["@id"]);
              }
            } catch(e) {
              console.log('ERROR OsdRegionDrawTool#render anno:', annotation, 'error:', e);
            }
          }
    
          var windowElement = _this.state.getWindowElement(_this.windowId);
          this.annoTooltip = new $.AnnotationTooltip({
            targetElement: jQuery(this.osdViewer.element),
            state: _this.state,
            eventEmitter: _this.eventEmitter,
            windowId: _this.windowId
          });
          this.annoTooltip.initializeViewerUpgradableToEditor({
            container: windowElement,
            viewport: windowElement,
            getAnnoFromRegion: _this.getAnnoFromRegion.bind(this)
          });
          this.svgOverlay.paperScope.view.draw();
          _this.eventEmitter.publish('annotationsRendered.' + _this.windowId);
        },
    
        prepareShapeArray: function(annotation, strategies) {
          if (typeof annotation === 'object' && annotation.on) {
            for (var i = 0; i < strategies.length; i++) {
              if (strategies[i].isThisType(annotation)) {
                shapeArray = strategies[i].parseRegion(annotation, this);
                return shapeArray;
              }
            }
          }
          return [];
        },
    
        parseRectangle: function(rectString, annotation) {
          var shapeArray = rectString.split('=')[1].split(','),
          shape = {
            'x': parseInt(shapeArray[0]),
            'y': parseInt(shapeArray[1]),
            'width': parseInt(shapeArray[2]),
            'height': parseInt(shapeArray[3])
          };
    
          return this.svgOverlay.createRectangle(shape, annotation);
        },
    
        showTooltipsFromMousePosition: function(event, location, absoluteLocation) {
          var _this = this;
          var originWindow = this.state.getWindowObjectById(this.windowId);
          var currentCanvasModel = originWindow.canvases[originWindow.canvasID];
    
          var hitOptions = {
            fill: true,
            stroke: true,
            segments: true
          };
          var hoverColor = this.state.getStateProperty('drawingToolsSettings').hoverColor;
          var annotations = [];
          if (this.horizontallyFlipped) {
            location.x = currentCanvasModel.getBounds().width - location.x;
          }
          for (var key in _this.annotationsToShapesMap) {
            if (_this.annotationsToShapesMap.hasOwnProperty(key)) {
              var shapeArray = _this.annotationsToShapesMap[key];
              for (var idx = 0; idx < shapeArray.length; idx++) {
                var shapeTool = this.svgOverlay.getTool(shapeArray[idx]);
                var hoverWidth = shapeArray[idx].data.strokeWidth / this.svgOverlay.paperScope.view.zoom;
                if (shapeArray[idx].hitTest(location, hitOptions)) {
                  annotations.push(shapeArray[idx].data.annotation);
                  if(shapeTool.onHover){
                    for(var k=0;k<shapeArray.length;k++){
                      shapeTool.onHover(true,shapeArray[k],hoverWidth,hoverColor);
                    }
                  }
                  break;
                }else{
                  if(shapeTool.onHover){
                    shapeTool.onHover(false,shapeArray[idx],hoverWidth);
                  }
                }
              }
            }
          }
          this.svgOverlay.paperScope.view.draw();
          //if (_this.svgOverlay.availableExternalCommentsPanel) {
         //   _this.eventEmitter.publish('annotationMousePosition.' + _this.windowId, [annotations]);
          //  return;
          //}
          _this.annoTooltip.showViewer({
            annotations: annotations,
            triggerEvent: event,
            shouldDisplayTooltip: function(api) {
              //track whether the cursor is within the tooltip (with the specified tolerance) and disables show/hide/update functionality.
              if (api.elements.tooltip) {
                var cursorWithinTooltip = true;
                var leftSide = api.elements.tooltip.offset().left - _this.svgOverlay.hitOptions.tolerance;
                var rightSide = api.elements.tooltip.offset().left + api.elements.tooltip.width() + _this.svgOverlay.hitOptions.tolerance;
                if (absoluteLocation.x < leftSide || rightSide < absoluteLocation.x) {
                  cursorWithinTooltip = false;
                }
                var topSide = api.elements.tooltip.offset().top - _this.svgOverlay.hitOptions.tolerance;
                var bottomSide = api.elements.tooltip.offset().top + api.elements.tooltip.height() + _this.svgOverlay.hitOptions.tolerance;
                if (absoluteLocation.y < topSide || bottomSide < absoluteLocation.y) {
                  cursorWithinTooltip = false;
                }
                return !cursorWithinTooltip;
              }
              return true;
            }
          });
        },
    
        listenForActions: function() {
          var _this = this;
    
          this._thisDestroy = function(){
            _this.destroy();
          };
    
          _this.osdViewer.addHandler('close', this._thisDestroy);
    
          this.eventsSubscriptions.push(this.eventEmitter.subscribe('DESTROY_EVENTS.'+this.windowId, function(event) {
            _this.destroy();
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('updateTooltips.' + _this.windowId, function(event, location, absoluteLocation) {
            if (_this.annoTooltip && !_this.annoTooltip.inEditOrCreateMode) {
              _this.showTooltipsFromMousePosition(event, location, absoluteLocation);
            }
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('removeTooltips.' + _this.windowId, function() {
            jQuery(_this.osdViewer.element).qtip('destroy', true);
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('disableTooltips.' + _this.windowId, function() {
            if (_this.annoTooltip) {
              _this.annoTooltip.inEditOrCreateMode = true;
            }
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('enableTooltips.' + _this.windowId, function() {
            if (_this.annoTooltip) {
              _this.annoTooltip.inEditOrCreateMode = false;
            }
            _this.svgOverlay.restoreDraftShapes();
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('SET_ANNOTATION_EDITING.' + _this.windowId, function(event, options) {
            jQuery.each(_this.annotationsToShapesMap, function(key, paths) {
              // if we have a matching annotationId, pass the boolean value on for each path, otherwise, always pass false
              if (key === options.annotationId) {
                if (options.isEditable) {
                  _this.eventEmitter.publish('SET_OVERLAY_TOOLTIP.' + _this.windowId, {"tooltip" : options.tooltip, "visible" : true, "paths" : paths});
                } else {
                  _this.eventEmitter.publish('SET_OVERLAY_TOOLTIP.' + _this.windowId, {"tooltip" : null, "visible" : false, "paths" : []});
                }
                jQuery.each(paths, function(index, path) {
                  path.data.editable = options.isEditable;
                  if (options.isEditable) {
                    path.strokeWidth = (path.data.strokeWidth + 5) / _this.svgOverlay.paperScope.view.zoom;
                  } else {
                    path.strokeWidth = path.data.strokeWidth / _this.svgOverlay.paperScope.view.zoom;
                  }
                  //just in case, force the shape to be non hovered
                  var tool = _this.svgOverlay.getTool(path);
                  tool.onHover(false, path, path.strokeWidth);
                });
              } else {
                jQuery.each(paths, function(index, path) {
                  path.data.editable = false;
                });
              }
            });
            _this.svgOverlay.paperScope.view.draw();
          }));
    
          this.eventsSubscriptions.push(_this.eventEmitter.subscribe('refreshOverlay.' + _this.windowId, function (event) {
            _this.render();
          }));
    
          this.eventsSubscriptions.push(this.eventEmitter.subscribe("enableManipulation",function(event, tool){
            if(tool === 'mirror') {
              _this.horizontallyFlipped = true;
            }
          }));
          this.eventsSubscriptions.push(this.eventEmitter.subscribe("disableManipulation",function(event, tool){
            if(tool === 'mirror') {
              _this.horizontallyFlipped = false;
            }
          }));
        },
    
        getAnnoFromRegion: function(regionId) {
          return this.list.filter(function(annotation) {
            return annotation['@id'] === regionId;
          });
        },
    
        destroy: function () {
          var _this = this;
          this.eventsSubscriptions.forEach(function(event){
            _this.eventEmitter.unsubscribe(event.name,event.handler);
          });
          this.osdViewer.removeHandler('close', this._thisDestroy);
        }
    
      };
    }(Mirador));