Mercurial > hg > digilib
changeset 1253:4d1a50cd41c1
vector plugin assembles svg elementwise now.
author | robcast |
---|---|
date | Fri, 17 Jan 2014 14:57:20 +0100 |
parents | d059d9a8a401 |
children | 7410a158ca7b |
files | webapp/src/main/webapp/jquery/jquery.digilib.css webapp/src/main/webapp/jquery/jquery.digilib.js webapp/src/main/webapp/jquery/jquery.digilib.vector.js |
diffstat | 3 files changed, 139 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/jquery.digilib.css Fri Jan 17 12:45:56 2014 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.css Fri Jan 17 14:57:20 2014 +0100 @@ -394,6 +394,9 @@ } /* SVG */ +div.dl-digilib .dl-svg-handle { + stroke: blue; +} div.dl-digilib .dl-svg-handle:hover { fill: red; }
--- a/webapp/src/main/webapp/jquery/jquery.digilib.js Fri Jan 17 12:45:56 2014 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.js Fri Jan 17 14:57:20 2014 +0100 @@ -1754,7 +1754,21 @@ }); }; - + /** + * return an id. + * uses the given id or creates a random string (with prefix). + * + * @param id default value + * @param prefix + */ + var createId = function (id, prefix) { + if (id != null && id != '') return id; + if (prefix == null) { + prefix = settings.cssPrefix; + } + return prefix+Date.now(); + }; + // fallback for console.log calls if (customConsole) { var logFunction = function(type) { @@ -1814,7 +1828,8 @@ centerOnScreen : centerOnScreen, withdraw : withdraw, isOnScreen : isOnScreen, - find : find + find : find, + createId : createId }; // hook digilib plugin into jquery
--- a/webapp/src/main/webapp/jquery/jquery.digilib.vector.js Fri Jan 17 12:45:56 2014 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.vector.js Fri Jan 17 14:57:20 2014 +0100 @@ -48,8 +48,11 @@ // affine geometry var geom = null; // plugin object with digilib data - var digilib; - + var digilib = null; + // SVG namespace + var svgNS = 'http://www.w3.org/2000/svg'; + + var buttons = { }; @@ -61,7 +64,9 @@ // default SVG stroke-width 'defaultStrokeWidth' : '2', // default SVG fill - 'defaultFill' : 'none' + 'defaultFill' : 'none', + // grab handle size + 'editHandleSize' : 10 }; var actions = { @@ -177,68 +182,103 @@ data.$svg.remove(); } var settings = data.settings; - var css = settings.cssPrefix; - var trafo = data.imgTrafo; - var svg = '<svg xmlns="http://www.w3.org/2000/svg"\ - viewBox="'+data.imgRect.getAsSvg()+'"\ - class="'+settings.cssPrefix+'overlay"\ - style="position:absolute; z-index:10; pointer-events:visiblePainted;">'; + var $svg = $(createSvg('svg', { + 'viewBox': data.imgRect.getAsSvg(), + 'class': settings.cssPrefix+'overlay', + 'style': 'position:absolute; z-index:10; pointer-events:none;'})); + // adjust svg element size and position (doesn't work with .adjustDiv()) + $svg.css(data.imgRect.getAsCss()); + data.$svg = $svg; for (var i in data.shapes) { - var vec = data.shapes[i]; - // use given id - var id = (vec.id != null) ? 'id="'+vec.id+'"' : ''; - // set properties - var props = vec.properties || {}; - var stroke = props['stroke'] || settings.defaultStroke; - var strokeWidth = props['stroke-width'] || settings.defaultStrokeWidth; - var fill = props['fill'] || settings.defaultFill; - var coords = vec.geometry.coordinates; - var gt = vec.geometry.type; - if (gt === 'Line') { - /* - * Line - */ - var p1 = trafo.transform(geom.position(coords[0][0], coords[0][1])); - var p2 = trafo.transform(geom.position(coords[1][0], coords[1][1])); - svg += '<line '+id+'\ - x1="'+p1.x+'" y1="'+p1.y+'"\ - x2="'+p2.x+'" y2="'+p2.y+'"\ - stroke="'+stroke+'" stroke-width="'+strokeWidth+'"\ - />'; - if (props.editable != null) { - svg += '<rect \ - x="'+(p1.x-5)+'" y="'+(p1.y-5)+'" width="10" height="10"\ - stroke="darkgrey" stroke-width="1" fill="none"\ - class="'+css+'svg-handle"/>'; - /* svg += '<circle \ - cx="'+p1.x+'" cy="'+p1.y+'" r="5"\ - stroke="blue" stroke-width="1" fill="none"\ - class="'+css+'svg-handle"/>'; */ - } - } else if (gt === 'Rectangle') { - /* - * Rectangle - */ - var p1 = trafo.transform(geom.position(coords[0][0], coords[0][1])); - var p2 = trafo.transform(geom.position(coords[1][0], coords[1][1])); - var rect = geom.rectangle(p1, p2); - svg += '<rect '+id+'\ - x="'+rect.x+'" y="'+rect.y+'"\ - width="'+rect.width+'" height="'+rect.height+'"\ - stroke="'+stroke+'" stroke-width="'+strokeWidth+'"\ - fill="'+fill+'"\ - />'; - }; + var shape = data.shapes[i]; + renderShape(data, shape, $svg); } - svg += '</svg>'; - $svg = $(svg); data.$elem.append($svg); - data.$svg = $svg; - // adjust svg element size and position (doesn't work with .adjustDiv()) - data.$svg.css(data.imgRect.getAsCss()); }; - + /** + * render a shape on screen. + * + * Creates a SVG element and adds it to $svg. + * Puts a reference to the element in the shape object. + */ + var renderShape = function (data, shape, $svg) { + if ($svg == null) { + if (data.$svg == null) { + renderShapes(data); + } + $svg = data.$svg; + } + var settings = data.settings; + var css = settings.cssPrefix; + var hs = settings.editHandleSize; + var trafo = data.imgTrafo; + // use given id + var id = digilib.fn.createId(shape.id, css+'svg-'); + // set properties + var props = shape.properties || {}; + var stroke = props['stroke'] || settings.defaultStroke; + var strokeWidth = props['stroke-width'] || settings.defaultStrokeWidth; + var fill = props['fill'] || settings.defaultFill; + var coords = shape.geometry.coordinates; + var gt = shape.geometry.type; + if (gt === 'Line') { + /* + * Line + */ + var p1 = trafo.transform(geom.position(coords[0])); + var p2 = trafo.transform(geom.position(coords[1])); + var $elem = $(createSvg('line', { + 'id': id, + 'x1': p1.x, 'y1': p1.y, + 'x2': p2.x, 'y2': p2.y, + 'stroke': stroke, 'stroke-width': strokeWidth})); + shape.$elem = $elem; + $svg.append($elem); + if (props.editable) { + var e1 = createSvg('rect', { + 'x': p1.x-hs/2, 'y': p1.y-hs/2, 'width': hs, 'height': hs, + 'stroke': 'darkgrey', 'stroke-width': 1, 'fill': 'none', + 'class': css+'svg-handle', 'style': 'pointer-events:all'}); + var e2 = createSvg('rect', { + 'x': p2.x-hs/2, 'y': p2.y-hs/2, 'width': hs, 'height': hs, + 'stroke': 'darkgrey', 'stroke-width': 1, 'fill': 'none', + 'class': css+'svg-handle', 'style': 'pointer-events:all'}); + var $editElems = $([e1, e2]); + shape.$editElems = $editElems; + $svg.append($editElems); + } + } else if (gt === 'Rectangle') { + /* + * Rectangle + */ + var p1 = trafo.transform(geom.position(coords[0])); + var p2 = trafo.transform(geom.position(coords[1])); + var rect = geom.rectangle(p1, p2); + var $elem = $(createSvg('rect', { + 'id': id, + 'x': rect.x, 'y': rect.y, + 'width': rect.width, 'height': rect.height, + 'stroke': stroke, 'stroke-width': strokeWidth, + 'fill': fill})); + shape.$elem = $elem; + $svg.append($elem); + if (props.editable) { + var e1 = createSvg('rect', { + 'x': p1.x-hs/2, 'y': p1.y-hs/2, 'width': hs, 'height': hs, + 'stroke': 'darkgrey', 'stroke-width': 1, 'fill': 'none', + 'class': css+'svg-handle', 'style': 'pointer-events:all'}); + var e2 = createSvg('rect', { + 'x': p2.x-hs/2, 'y': p2.y-hs/2, 'width': hs, 'height': hs, + 'stroke': 'darkgrey', 'stroke-width': 1, 'fill': 'none', + 'class': css+'svg-handle', 'style': 'pointer-events:all'}); + var $editElems = $([e1, e2]); + shape.$editElems = $editElems; + $svg.append($editElems); + } + } + }; + var handleUpdate = function (evt) { console.debug("vector: handleUpdate"); var data = this; @@ -257,11 +297,8 @@ 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; + shapeId = digilib.fn.createId(shapeId, data.settings.cssPrefix+'shape-'); + shape.id = shapeId; var $elem = data.$elem; var $scaler = data.$scaler; var picRect = geom.rectangle($scaler); @@ -269,7 +306,7 @@ 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;"/>'); + var $overlayDiv = $('<div class="'+data.settings.cssPrefix+'shapeOverlay" style="position:absolute; z-index:100;"/>'); $elem.append($overlayDiv); bodyRect.adjustDiv($overlayDiv); // shape element reference @@ -281,9 +318,8 @@ if (shapeType === 'Line' || shapeType === 'Rectangle') { shape.geometry.coordinates = [[p1.x, p1.y], [p1.x, p1.y]]; } - data.shapes.push(shape); - renderShapes(data); - $shape = $('#'+shapeId); + renderShape(data, shape); + $shape = shape.$elem; // register events $overlayDiv.on("mousemove.dlShape", shapeMove); $overlayDiv.on("mouseup.dlShape", shapeEnd); @@ -329,6 +365,7 @@ shape.geometry.coordinates[1] = [p2.x, p2.y]; } console.debug("new shape:", shape); + data.shapes.push(shape); $overlayDiv.remove(); if (onComplete != null) { onComplete(data, shape); @@ -340,6 +377,19 @@ $overlayDiv.one('mousedown.dlShape', shapeStart); }; + /** + * create a SVG element + */ + var createSvg = function (name, attrs) { + var elem = document.createElementNS(svgNS, name); + if (attrs != null) { + for (var att in attrs) { + elem.setAttributeNS(null, att, attrs[att]); + }; + } + return elem; + }; + // plugin object, containing name, install and init routines // all shared objects are filled by digilib on registration var plugin = {