Mercurial > hg > digilib-old
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
--- 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"
--- /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); } },