changeset 1083:bab0bdac6d92

first version of annotations plugin. moved mark background image.
author robcast
date Wed, 30 May 2012 21:42:44 +0200
parents 6407c33355a2
children 1d3e8f853b9c
files webapp/src/main/webapp/jquery/img/annotationmark-bg-16.png webapp/src/main/webapp/jquery/img/fullscreen/32/annotation-mark.png webapp/src/main/webapp/jquery/img/fullscreen/32/annotations.png webapp/src/main/webapp/jquery/img/fullscreen/old/mark-bg-16.png webapp/src/main/webapp/jquery/img/fullscreen/old/mark-bg.png webapp/src/main/webapp/jquery/img/fullscreen3.svg webapp/src/main/webapp/jquery/img/mark-bg-16.png webapp/src/main/webapp/jquery/img/mark-bg.png webapp/src/main/webapp/jquery/jquery.digilib.annotations.js webapp/src/main/webapp/jquery/jquery.digilib.css webapp/src/main/webapp/jquery/jquery.digilib.marks.js
diffstat 11 files changed, 409 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
Binary file webapp/src/main/webapp/jquery/img/annotationmark-bg-16.png has changed
Binary file webapp/src/main/webapp/jquery/img/fullscreen/32/annotation-mark.png has changed
Binary file webapp/src/main/webapp/jquery/img/fullscreen/32/annotations.png has changed
Binary file webapp/src/main/webapp/jquery/img/fullscreen/old/mark-bg-16.png has changed
Binary file webapp/src/main/webapp/jquery/img/fullscreen/old/mark-bg.png has changed
--- a/webapp/src/main/webapp/jquery/img/fullscreen3.svg	Wed May 30 15:26:49 2012 +0200
+++ b/webapp/src/main/webapp/jquery/img/fullscreen3.svg	Wed May 30 21:42:44 2012 +0200
@@ -76,9 +76,9 @@
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
      inkscape:zoom="14.74"
-     inkscape:cx="15.247365"
+     inkscape:cx="3.1713813"
      inkscape:cy="15.995577"
-     inkscape:current-layer="layer1"
+     inkscape:current-layer="g4128"
      showgrid="true"
      inkscape:grid-bbox="true"
      inkscape:document-units="px"
@@ -122,7 +122,7 @@
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
+        <dc:title />
       </cc:Work>
     </rdf:RDF>
   </metadata>
@@ -149,7 +149,7 @@
      sodipodi:insensitive="true">
     <path
        transform="matrix(0.87955865,0,0,0.86576173,-2.7623298,1.2980787)"
-       d="m 48.142857,26.214285 a 17.928572,18.214285 0 1 1 -35.857144,0 17.928572,18.214285 0 1 1 35.857144,0 z"
+       d="m 48.142857,26.214285 c 0,10.059472 -8.026895,18.214285 -17.928572,18.214285 -9.901677,0 -17.928572,-8.154813 -17.928572,-18.214285 C 12.285713,16.154813 20.312608,8 30.214285,8 c 9.901677,0 17.928572,8.154813 17.928572,18.214285 z"
        sodipodi:ry="18.214285"
        sodipodi:rx="17.928572"
        sodipodi:cy="26.214285"
@@ -249,7 +249,7 @@
          sodipodi:cy="12.5"
          sodipodi:rx="10.214286"
          sodipodi:ry="10.214286"
-         d="m 44.857142,12.5 a 10.214286,10.214286 0 1 1 -20.428571,0 10.214286,10.214286 0 1 1 20.428571,0 z"
+         d="m 44.857142,12.5 c 0,5.641194 -4.573091,10.214286 -10.214285,10.214286 -5.641195,0 -10.214286,-4.573092 -10.214286,-10.214286 0,-5.6411943 4.573091,-10.2142859 10.214286,-10.2142859 5.641194,0 10.214285,4.5730916 10.214285,10.2142859 z"
          transform="translate(-10.42857,10.28571)" />
       <g
          style="fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:1.08393705"
@@ -315,7 +315,7 @@
        sodipodi:cy="23.66371"
        sodipodi:rx="4.2291727"
        sodipodi:ry="4.3775644"
-       d="m 29.604207,23.66371 a 4.2291727,4.3775644 0 1 1 -8.458345,0 4.2291727,4.3775644 0 1 1 8.458345,0 z"
+       d="m 29.604207,23.66371 c 0,2.417662 -1.893465,4.377564 -4.229173,4.377564 -2.335707,0 -4.229172,-1.959902 -4.229172,-4.377564 0,-2.417662 1.893465,-4.377565 4.229172,-4.377565 2.335708,0 4.229173,1.959903 4.229173,4.377565 z"
        transform="matrix(1.2610819,0,0,1.2183335,-7.993339,-4.8302894)" />
   </g>
   <g
@@ -551,6 +551,74 @@
          style="fill:#ffffff">1</tspan></text>
   </g>
   <g
+     transform="translate(-7.8129058,-7.9934033)"
+     style="display:none"
+     inkscape:label="annotation-mark"
+     id="g3345"
+     inkscape:groupmode="layer"
+     sodipodi:insensitive="true">
+    <g
+       id="g3353"
+       transform="translate(-1.238881,-2.9520324)">
+      <rect
+         style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.82051283;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect3347"
+         width="13.073231"
+         height="13.118359"
+         x="17.470043"
+         y="17.440821" />
+      <text
+         xml:space="preserve"
+         style="font-size:13.1282053px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+         x="19.716681"
+         y="28.777008"
+         id="text3349"
+         sodipodi:linespacing="125%"><tspan
+           sodipodi:role="line"
+           id="tspan3351"
+           x="19.716681"
+           y="28.777008"
+           style="fill:#ffffff">1</tspan></text>
+    </g>
+    <path
+       style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 21.765939,21.488404 11.278998,0 c -1.773025,8.409248 3.823753,4.013599 2.050729,12.004999 l -11.343086,0 C 25.482882,25.40112 19.907466,29.975104 21.765939,21.488404 z"
+       id="path3358"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="g4128"
+     inkscape:label="annotations"
+     style="display:none"
+     transform="translate(-7.8129058,-7.9934033)"
+     sodipodi:insensitive="true">
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path4138"
+       d="m 15.77761,16.487137 13.631663,0 c -2.142857,10.515962 4.621342,5.019099 2.478486,15.012533 l -13.709119,0 C 20.269862,21.380081 13.531481,27.099955 15.77761,16.487137 z"
+       style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       d="m 10.922659,11.986431 8.208956,0 0,0"
+       id="path4140"
+       inkscape:connector-curvature="0"
+       transform="translate(7.8129058,7.9934033)" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       d="m 19.906529,24.050391 6.852103,0"
+       id="path4142"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       d="m 21.906529,27.985262 7.055631,0.06784"
+       id="path4144"
+       inkscape:connector-curvature="0" />
+  </g>
+  <g
      inkscape:groupmode="layer"
      id="layer27"
      inkscape:label="mirror-vertical"
@@ -1210,7 +1278,7 @@
          style="fill:none;stroke:#000000;stroke-width:3.0204308;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
       <path
          transform="matrix(1.088683,0,0,1.172638,-8.8022,17.946136)"
-         d="m 24.857143,16.857143 a 6,5.5714288 0 1 1 -12,0 6,5.5714288 0 1 1 12,0 z"
+         d="m 24.857143,16.857143 c 0,3.077016 -2.686291,5.571429 -6,5.571429 -3.313708,0 -6,-2.494413 -6,-5.571429 0,-3.077015 2.686292,-5.571428 6,-5.571428 3.313709,0 6,2.494413 6,5.571428 z"
          sodipodi:ry="5.5714288"
          sodipodi:rx="6"
          sodipodi:cy="16.857143"
@@ -1229,7 +1297,7 @@
      sodipodi:insensitive="true">
     <path
        transform="matrix(0.86721436,0,0,0.90813654,0.46798366,6.0967375)"
-       d="m 37.571428,19.714285 a 10.428572,10.142858 0 1 1 -20.857143,0 10.428572,10.142858 0 1 1 20.857143,0 z"
+       d="m 37.571428,19.714285 c 0,5.601745 -4.66903,10.142857 -10.428571,10.142857 -5.759542,0 -10.428572,-4.541112 -10.428572,-10.142857 0,-5.601746 4.66903,-10.1428577 10.428572,-10.1428577 5.759541,0 10.428571,4.5411117 10.428571,10.1428577 z"
        sodipodi:ry="10.142858"
        sodipodi:rx="10.428572"
        sodipodi:cy="19.714285"
@@ -1270,7 +1338,7 @@
        sodipodi:cy="19.714285"
        sodipodi:rx="10.428572"
        sodipodi:ry="10.142858"
-       d="m 37.571428,19.714285 a 10.428572,10.142858 0 1 1 -20.857143,0 10.428572,10.142858 0 1 1 20.857143,0 z"
+       d="m 37.571428,19.714285 c 0,5.601745 -4.66903,10.142857 -10.428571,10.142857 -5.759542,0 -10.428572,-4.541112 -10.428572,-10.142857 0,-5.601746 4.66903,-10.1428577 10.428572,-10.1428577 5.759541,0 10.428571,4.5411117 10.428571,10.1428577 z"
        transform="matrix(0.86721436,0,0,0.90813654,0.46798366,6.0967375)" />
     <path
        style="fill:none;stroke:#000000;stroke-width:4.10256433;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
Binary file webapp/src/main/webapp/jquery/img/mark-bg-16.png has changed
Binary file webapp/src/main/webapp/jquery/img/mark-bg.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.annotations.js	Wed May 30 21:42:44 2012 +0200
@@ -0,0 +1,313 @@
+/**
+ digilib plugin for annotations.
+
+ currently only point-like (like marks).
+
+ */
+
+(function($) {
+
+    // affine geometry
+    var geom;
+    // plugin object with digilib data
+    var digilib;
+
+    var FULL_AREA;
+
+    var buttons = {
+        annotations : {
+            onclick : "toggleAnnotations",
+            tooltip : "show or hide annotations",
+            icon : "annotations.png"
+        },
+        annotationmark : {
+            onclick : "setAnnotationMark",
+            tooltip : "create an annotation for a point",
+            icon : "annotation-mark.png"
+        }
+    };
+
+    var defaults = {
+        // are annotations active?
+        'isAnnotationsVisible' : true,
+        // buttonset of this plugin
+        'annotationSet' : ['annotations', 'annotationmark', 'lessoptions'],
+        // URL of annotation server
+        'annotationServerUrl' : 'http://virtuoso.mpiwg-berlin.mpg.de:8080/AnnotationManager/annotator',
+        // URL of authentication token server
+        'annotationTokenUrl' : 'http://localhost:8080/test/annotator/token?user=anonymous',
+        // annotation user name
+        'annotationUser' : 'anonymous'
+    };
+
+    var actions = {
+        /**
+         * show/hide annotations
+         */
+        toggleAnnotations : function(data) {
+            var show = !data.settings.isAnnotationsVisible;
+            data.settings.isAnnotationsVisible = show;
+            fn.highlightButtons(data, 'annotations', show);
+            renderAnnotations(data);
+        },
+
+        /**
+         * set a mark-annotation by clicking (or giving a position and a text)
+         *
+         * @param data
+         * @param mpos
+         * @param text
+         */
+        setAnnotationMark : function(data, mpos, text) {
+            if (mpos == null) {
+                // interactive
+                setAnnotationMark(data);
+            } else {
+                // use position and text
+                var annotation = newAnnotation(mpos, text);
+                storeAnnotation(data, annotation);
+                data.annotations.push(annotation);
+                digilib.fn.redisplay(data);
+            }
+        },
+    };
+
+    var newAnnotation = function(mpos, text, id, uri, user) {
+        var annot = {
+            pos : mpos,
+            text : text,
+            id : id,
+            uri : uri,
+            user : user
+        };
+        return annot;
+    };
+
+    /**
+     * returns an annotatable url to this digilib image
+     */
+    var getAnnotationPageUrl = function(data) {
+        var url = data.settings.digilibBaseUrl + '/jquery/digilib.html?';
+        url += digilib.fn.getParamString(data.settings, ['fn', 'pn'], digilib.defaults);
+        return url;
+    }
+
+    /**
+     * add a mark-annotation where clicked.
+     *
+     */
+    var setAnnotationMark = function(data) {
+        var $scaler = data.$scaler;
+        // unbind other handler TODO: do we need to do this?
+        $scaler.off(".dlZoomDrag");
+        // start event capturing
+        $scaler.one('mousedown.dlSetAnnotationMark', function(evt) {
+            // event handler adding a new mark
+            console.log("setAnnotationMark at=", evt);
+            var mpos = geom.position(evt);
+            var pos = data.imgTrafo.invtransform(mpos);
+            var text = window.prompt("Annotation text:");
+            if (text == null)
+                return false;
+            var annotation = newAnnotation(pos, text);
+            storeAnnotation(data, annotation);
+            data.annotations.push(annotation);
+            digilib.fn.redisplay(data);
+            return false;
+        });
+    };
+
+    /**
+     * place annotations on the image
+     *
+     */
+    var renderAnnotations = function(data) {
+        if (data.annotations == null || data.$img == null || data.imgTrafo == null)
+            return;
+        var cssPrefix = data.settings.cssPrefix;
+        var $elem = data.$elem;
+        var annotations = data.annotations;
+        console.debug("renderAnnotations: annotations=" + annotations);
+        // clear annotations
+        $elem.find('div.' + cssPrefix + 'annotationmark').remove();
+        for (var i = 0; i < annotations.length; i++) {
+            var annotation = annotations[i];
+            if (data.zoomArea.containsPosition(annotation.pos)) {
+                var mpos = data.imgTrafo.transform(annotation.pos);
+                console.debug("renderannotations: pos=", mpos);
+                // create annotation
+                var html = '<div class="' + cssPrefix + 'annotationmark ' + cssPrefix + 'overlay">' + (i + 1) + '</div>';
+                var $annotation = $(html);
+                // set text as tooltip TODO: have real popup with editing
+                $annotation.attr('title', "Annotation: " + annotation.text);
+                $elem.append($annotation);
+                mpos.adjustDiv($annotation);
+            }
+        }
+    };
+
+    var loadAnnotationToken = function(data) {
+        var settings = data.settings;
+        var url = settings.annotationTokenUrl;
+        // TODO: better error handling
+        $.get(url, function(authToken, authStatus) {
+            console.debug("got auth token data=", authToken);
+            data.annotationToken = authToken;
+            loadAnnotations(data);
+        });
+    };
+
+    var loadAnnotations = function(data) {
+        var settings = data.settings;
+        var url = settings.annotationServerUrl + '/search';
+        var pageUrl = data.digilibBaseUrl + '/jquery/digilib.html?';
+        pageUrl += digilib.fn.getParamString(settings, ['fn', 'pn'], digilib.defaults);
+        // send authentication token in header
+        headers = {
+            'x-annotator-auth-token' : data.annotationToken
+        };
+        // get only annotations with this url
+        var query = {
+            limit : 20,
+            uri : pageUrl
+        };
+        $.ajax(url, {
+            dataType : 'json',
+            data : query,
+            headers : headers,
+            success : function(annotData, annotStatus) {
+                console.debug("got annotation data=", annotData);
+                data.annotationData = annotData;
+                parseAnnotations(data, annotData);
+                renderAnnotations(data);
+            }
+        });
+    };
+
+    var parseAnnotations = function(data, annotationData) {
+        var annotations = [];
+        for (var i = 0; i < annotationData.rows.length; ++i) {
+            var ann = annotationData.rows[i];
+            var annot = parseAnnotation(ann)
+            if (annot != null) {
+                annotations.push(annot);
+            }
+        }
+        data.annotations = annotations;
+    };
+
+    var parseAnnotation = function(ann) {
+        // TODO: check validity of annotation data
+        if (ann.area != null) {
+            var pos = geom.position(ann.area.x, ann.area.y);
+            return newAnnotation(pos, ann.text, ann.id, ann.uri, ann.user);
+        }
+        return null;
+    };
+
+    var storeAnnotation = function(data, annotation) {
+        console.debug("storeAnnotation:", annotation);
+        var settings = data.settings;
+        var url = settings.annotationServerUrl + '/annotations';
+        var pageUrl = getAnnotationPageUrl(data);
+        // send authentication token in header
+        headers = {
+            'x-annotator-auth-token' : data.annotationToken
+        };
+        // create annotation object to send
+        var annotData = {
+            area : {x : annotation.pos.x, y : annotation.pos.y},
+            text : annotation.text,
+            uri : pageUrl,
+            user : settings.annotationUser
+        };
+        var dataString = JSON.stringify(annotData);
+        $.ajax(url, {
+            type : 'POST',
+            dataType : 'json',
+            contentType : 'application/json',
+            data : dataString,
+            headers : headers,
+            success : function(annotData, annotStatus) {
+                console.debug("sent annotation data, got=", annotData, " status="+annotStatus);
+                var annot = parseAnnotation(annotData);
+                // TODO: we have to add the returned data to the real annotation!
+                //renderAnnotations(data);
+            }
+        });
+
+    }
+    /** install additional buttons */
+    var installButtons = function(data) {
+        var settings = data.settings;
+        var mode = settings.interactionMode;
+        var buttonSettings = settings.buttonSettings[mode];
+        // configure buttons through digilib "annotationSet" option
+        var buttonSet = settings.annotationSet || annotationSet;
+        // set annotationSet to [] or '' for no buttons (when showing annotations only)
+        if (buttonSet.length && buttonSet.length > 0) {
+            buttonSettings.annotationSet = buttonSet;
+            buttonSettings.buttonSets.push('annotationSet');
+        }
+    };
+
+    /** plugin installation called by digilib on plugin object. */
+    var install = function(plugin) {
+        digilib = plugin;
+        console.debug('installing annotations plugin. digilib:', digilib);
+        // import geometry classes
+        geom = digilib.fn.geometry;
+        FULL_AREA = geom.rectangle(0, 0, 1, 1);
+        // add defaults, actins, buttons
+        $.extend(digilib.defaults, defaults);
+        $.extend(digilib.actions, actions);
+        $.extend(digilib.buttons, buttons);
+    };
+
+    /** plugin initialization */
+    var init = function(data) {
+        console.debug('initialising annotations plugin. data:', data);
+        var $data = $(data);
+        // set up
+        data.annotations = [];
+        if (digilib.plugins.buttons != null) {
+            installButtons(data);
+        }
+        // install event handler
+        $data.bind('setup', handleSetup);
+        $data.bind('update', handleUpdate);
+    };
+
+    var handleSetup = function(evt) {
+        console.debug("annotations: handleSetup");
+        var data = this;
+        // load annotations from server
+        loadAnnotationToken(data);
+    };
+
+    var handleUpdate = function(evt) {
+        console.debug("annotations: handleUpdate");
+        var data = this;
+        if (data.marks != null) {
+            renderAnnotations(data);
+        }
+    };
+
+    // plugin object with name and init
+    // shared objects filled by digilib on registration
+    var plugin = {
+        name : 'annotations',
+        install : install,
+        init : init,
+        buttons : {},
+        actions : {},
+        fn : {},
+        plugins : {}
+    };
+
+    if ($.fn.digilib == null) {
+        $.error("jquery.digilib.annotations must be loaded after jquery.digilib!");
+    } else {
+        $.fn.digilib('plugin', plugin);
+    }
+})(jQuery);
--- a/webapp/src/main/webapp/jquery/jquery.digilib.css	Wed May 30 15:26:49 2012 +0200
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.css	Wed May 30 21:42:44 2012 +0200
@@ -42,17 +42,32 @@
 div.dl-digilib div.dl-mark {
 	position: absolute;
 	color: white;
-	background: url('../greyskin/mark-bg-16.png');
+	background: url('img/mark-bg-16.png');
 	font-family: Verdana, Arial, Helvetica, sans-serif;
 	font-weight: bold;
 	font-size: 11px;
-	height: 15px;
+	height: 16px;
 	width: 16px;
 	padding-top: 1px;
 	text-align: center;
 	z-index: 10;
 }
 
+div.dl-digilib div.dl-annotationmark {
+    position: absolute;
+    color: black;
+    background: url('img/annotationmark-bg-16.png');
+    /* background-color: yellow; */
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-weight: bold;
+    font-size: 11px;
+    height: 16px;
+    width: 16px;
+    padding-top: 1px;
+    text-align: center;
+    z-index: 10;
+}
+
 div.dl-digilib div.dl-about {
 	position: absolute;
 	padding: 10px;	
--- a/webapp/src/main/webapp/jquery/jquery.digilib.marks.js	Wed May 30 15:26:49 2012 +0200
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.marks.js	Wed May 30 21:42:44 2012 +0200
@@ -1,5 +1,5 @@
 /**
- * digilib plugin stub
+ * digilib marks plugin
  */
 
 (function($) {
@@ -38,7 +38,7 @@
                 setMark(data);
             } else {
                 // use position
-                data.marks.push(pos);
+                data.marks.push(mpos);
                 digilib.fn.redisplay(data);
             }
         },