Mercurial > hg > digilib
changeset 1244:8cb0faad875a
interactive creation of vector lines and rectangles.
author | robcast |
---|---|
date | Wed, 15 Jan 2014 22:32:42 +0100 |
parents | e69b80f99a00 |
children | 29c97a4e266e |
files | webapp/src/main/webapp/jquery/jquery.digilib.vector.js |
diffstat | 1 files changed, 112 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/jquery.digilib.vector.js Wed Jan 15 22:30:46 2014 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.vector.js Wed Jan 15 22:32:42 2014 +0100 @@ -60,17 +60,23 @@ }, /** - * add vector object (shape). + * add vector object (shape) or create by clicking. * * @param data * @param shape + * @param onComplete */ - addShape : function(data, shape) { + addShape : function(data, shape, onComplete) { if (data.shapes == null) { data.shapes = []; }; - data.shapes.push(shape); - renderShapes(data); + if (shape.geometry.coordinates == null) { + // define shape interactively + defineShape(data, shape, onComplete); + } else { + data.shapes.push(shape); + renderShapes(data); + } }, /** @@ -78,6 +84,7 @@ * * @param data * @param id + * @returns shape */ getShapeById : function(data, id) { shapes = data.shapes; @@ -137,8 +144,12 @@ }; var renderShapes = function (data) { + console.debug("renderShapes shapes:", data.shapes); if (data.shapes == null) return; if (!data.settings.isVectorActive) return; + if (data.$svg != null) { + data.$svg.remove(); + } var settings = data.settings; var svg = '<svg xmlns="http://www.w3.org/2000/svg"\ viewBox="0 0 1 1" preserveAspectRatio="none"\ @@ -158,8 +169,8 @@ * Line */ svg += '<line '+id+'\ - x1="'+coords[0][0]+'" y1="'+coords[0][0]+'"\ - x2="'+coords[1][0]+'" y2="'+coords[1][0]+'"\ + x1="'+coords[0][0]+'" y1="'+coords[0][1]+'"\ + x2="'+coords[1][0]+'" y2="'+coords[1][1]+'"\ stroke="'+stroke+'" stroke-width="'+strokeWidth+'"\ />'; } else if (gt === 'Rectangle') { @@ -180,7 +191,13 @@ svg += '</svg>'; $svg = $(svg); data.$elem.append($svg); - data.$svg = $svg; + data.$svg = $svg; + if (data.imgRect != null) { + // adjust svg element size and position (doesn't work with .adjustDiv()) + data.$svg.css(data.imgRect.getAsCss()); + // adjust zoom statue (use DOM setAttribute because jQuery lowercases attributes) + data.$svg.get(0).setAttribute("viewBox", data.zoomArea.getAsSvg()); + } }; @@ -196,6 +213,94 @@ } }; + /** define a shape by click and drag + * + */ + var defineShape = function(data, shape, onComplete) { + var shapeType = shape.geometry.type; + var shapeId = shape.id; + if (shapeId == null) { + shapeId = data.settings.cssPrefix+'shape-'+Date.now(); + shape.id = shapeId; + } + var CSS = data.settings.cssPrefix; + var $elem = data.$elem; + var $scaler = data.$scaler; + var picRect = geom.rectangle($scaler); + var $body = $('body'); + var bodyRect = geom.rectangle($body); + var pt1, pt2; + // overlay div prevents other elements from reacting to mouse events + var $overlayDiv = $('<div class="'+CSS+'shapeOverlay" style="position:absolute; z-index:100;"/>'); + $elem.append($overlayDiv); + bodyRect.adjustDiv($overlayDiv); + // shape element reference + var $shape = null; + var shapeStart = function (evt) { + pt1 = geom.position(evt); + // setup and show shape + p1 = data.imgTrafo.invtransform(pt1); + if (shapeType === 'Line' || shapeType === 'Rectangle') { + shape.geometry.coordinates = [[p1.x, p1.y], [p1.x, p1.y]]; + } + data.shapes.push(shape); + renderShapes(data); + $shape = $('#'+shapeId); + // register events + $overlayDiv.on("mousemove.dlShape", shapeMove); + $overlayDiv.on("mouseup.dlShape", shapeEnd); + return false; + }; + + // mouse move handler + var shapeMove = function (evt) { + pt2 = geom.position(evt); + pt2.clipTo(picRect); + // update shape + if (shapeType === 'Line') { + var p2 = data.imgTrafo.invtransform(pt2); + $shape.attr({'x2': p2.x, 'y2': p2.y}); + } else if (shapeType === 'Rectangle') { + var clickRect = geom.rectangle(pt1, pt2); + var rect = data.imgTrafo.invtransform(clickRect); + $shape.attr({'x': rect.x, 'y': rect.y, + 'width': rect.width, 'height': rect.height}); + } + return false; + }; + + // mouseup handler: end moving + var shapeEnd = function (evt) { + pt2 = geom.position(evt); + // assume a click and continue if the area is too small + var clickRect = geom.rectangle(pt1, pt2); + if (clickRect.width < 5 && clickRect.height < 5) { + if (onComplete != null) { + onComplete(data, null); + } + return false; + }; + // unregister events + $overlayDiv.off("mousemove.dlShape", shapeMove); + $overlayDiv.off("mouseup.dlShape", shapeEnd); + // clip and transform + clickRect.clipTo(picRect); + var rect = data.imgTrafo.invtransform(clickRect); + // update shape + var p2 = rect.getPt2(); + shape.geometry.coordinates = [[rect.x, rect.y], [p2.x, p2.y]]; + console.debug("new shape:", shape); + $overlayDiv.remove(); + if (onComplete != null) { + onComplete(data, shape); + } + return false; + }; + + // start by clicking + $overlayDiv.one('mousedown.dlShape', shapeStart); + }; + // plugin object, containing name, install and init routines // all shared objects are filled by digilib on registration var plugin = {