From b2f2df4eac2a7161032022dc78b6b1c5a32e745e Mon Sep 17 00:00:00 2001 From: Alexis Deveria Date: Thu, 22 Jul 2010 19:10:51 +0000 Subject: [PATCH] Added convert-to-group option for SVG elements, added label (title) field for groups/SVGs git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1643 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/svg-editor.html | 10 ++ editor/svg-editor.js | 29 +++++- editor/svgcanvas.js | 218 +++++++++++++++++++++++++++++++---------- 3 files changed, 199 insertions(+), 58 deletions(-) diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 4c20abe4..70e0183f 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -227,6 +227,12 @@ script type="text/javascript" src="locale/locale.min.js">
+ + +
@@ -352,6 +358,10 @@ script type="text/javascript" src="locale/locale.min.js"> + +
+ +
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index d71dd3fa..2eb9d2d2 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -207,7 +207,15 @@ var extFunc = function() { $.each(curConfig.extensions, function() { - $.getScript(curConfig.extPath + this); + var extname = this; + $.getScript(curConfig.extPath + extname, function(d) { + // Fails locally in Chrome 5 + if(!d) { + var s = document.createElement('script'); + s.src = curConfig.extPath + extname; + document.querySelector('head').appendChild(s); + } + }); }); } @@ -1277,7 +1285,7 @@ } var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false; $('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,\ - #ellipse_panel, #line_panel, #text_panel, #image_panel').hide(); + #ellipse_panel, #line_panel, #text_panel, #image_panel, #gsvg_panel').hide(); if (elem != null) { var elname = elem.nodeName; @@ -1366,13 +1374,14 @@ circle: ['cx','cy','r'], ellipse: ['cx','cy','rx','ry'], line: ['x1','y1','x2','y2'], - text: [] + text: [], + gsvg: [] }; var el_name = elem.tagName; if($(elem).data('gsvg')) { - el_name = 'svg'; + $('#gsvg_panel').show(); } if(panels[el_name]) { @@ -1411,6 +1420,11 @@ var href = elem.getAttributeNS(xlinkNS, "href"); setImageURL(href); } // image + else if(el_name == 'g') { + console.log('is group'); + var title = svgCanvas.getTitle(); + $('#g_title').val(title); + } } } // if (elem != null) else if (multiselected) { @@ -1605,6 +1619,11 @@ $('#image_url').change(function(){ setImageURL(this.value); }); + + $('#g_title').change(function() { + svgCanvas.setGroupTitle(this.value); + $(this).width(17 + this.value.length * 5); + }); $('.attr_changer').change(function() { var attr = this.getAttribute("data-attr"); @@ -2140,7 +2159,7 @@ svgCanvas.moveToBottomSelectedElement(); } }; - + var convertToPath = function() { if (selectedElement != null) { svgCanvas.convertToPath(); diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 73c415b8..197277ca 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -3279,6 +3279,22 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) { if (!childTlist) continue; var m = transformListToTransform(childTlist).matrix; + + // Convert a matrix to a scale if applicable +// if(hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) { +// if(m.b==0 && m.c==0 && m.e==0 && m.f==0) { +// childTlist.removeItem(0); +// var translateOrigin = svgroot.createSVGTransform(), +// scale = svgroot.createSVGTransform(), +// translateBack = svgroot.createSVGTransform(); +// translateOrigin.setTranslate(0, 0); +// scale.setScale(m.a, m.d); +// translateBack.setTranslate(0, 0); +// childTlist.appendItem(translateBack); +// childTlist.appendItem(scale); +// childTlist.appendItem(translateOrigin); +// } +// } var angle = getRotationAngle(child); var old_start_transform = start_transform; @@ -3444,6 +3460,8 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) { start_transform = child.getAttribute("transform"); var childTlist = getTransformList(child); + if (!childTlist) continue; + var em = matrixMultiply(m, transformListToTransform(childTlist).matrix); var e2m = svgroot.createSVGTransform(); e2m.setMatrix(em); @@ -7827,6 +7845,89 @@ var uniquifyElems = this.uniquifyElems = function(g) { obj_num++; } +// Function: svgToGroup +// Converts a child SVG element to a group +var svgToGroup = this.svgToGroup = function(elem) { + if(!elem) { + elem = selectedElements[0]; + } + if(elem.tagName == 'g') { + // Use the gsvg as the new group + var svg = elem.firstChild; + var pt = $(svg).attr(['x', 'y']); + + $(elem.firstChild.firstChild).unwrap(); + $(elem).removeData('gsvg'); + + var tlist = getTransformList(elem); + var xform = svgroot.createSVGTransform(); + xform.setTranslate(pt.x, pt.y); + tlist.appendItem(xform); + recalculateDimensions(elem); + call("selected", [elem]); +// addToSelection(elem]); + return; +// elem = $(elem).data('gsvg'); + } + if(elem.tagName != 'svg') return; + + var g = svgdoc.createElementNS(svgns, "g"); + while (elem.hasChildNodes()) + g.appendChild(elem.firstChild); +// if (ts) +// g.setAttribute("transform", ts); + + var parent = elem.parentNode; + + if(parent) parent.removeChild(elem); + + uniquifyElems(g); + + // now give the g itself a new id + g.id = getNextId(); + + current_layer.appendChild(g); + + // change image href vals if possible +// $(svgcontent).find('image').each(function() { +// var image = this; +// preventClickDefault(image); +// var val = this.getAttributeNS(xlinkns, "href"); +// if(val.indexOf('data:') === 0) { +// // Check if an SVG-edit data URI +// var m = val.match(/svgedit_url=(.*?);/); +// if(m) { +// var url = decodeURIComponent(m[1]); +// $(new Image()).load(function() { +// image.setAttributeNS(xlinkns,'xlink:href',url); +// }).attr('src',url); +// } +// } +// // Add to encodableImages if it loads +// canvas.embedImage(val); +// }); + + + var batchCmd = new BatchCommand(); + + if(parent) { + batchCmd.addSubCommand(new RemoveElementCommand(elem, parent)); + batchCmd.addSubCommand(new InsertElementCommand(g)); + } + + // recalculate dimensions on the top-level children so that unnecessary transforms + // are removed + walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}}); + +// batchCmd.addSubCommand(new InsertElementCommand(svgcontent)); + + // reset transform lists +// svgTransformLists = {}; + clearSelection(); + addToSelection([g]); + addCommandToHistory(batchCmd); +} + // // Function: setSvgString // This function sets the current drawing as the input SVG XML. @@ -8084,62 +8185,15 @@ this.importSvgString = function(xmlString, toElements) { return; } + var g = svgToGroup(importedNode); + + // TODO: Find way to add this in a recalculateDimensions-parsable way // if (vb[0] != 0 || vb[1] != 0) // ts = "translate(" + (-vb[0]) + "," + (-vb[1]) + ") " + ts; // add all children of the imported to the we create - var g = svgdoc.createElementNS(svgns, "g"); - while (importedNode.hasChildNodes()) - g.appendChild(importedNode.firstChild); - if (ts) - g.setAttribute("transform", ts); - - uniquifyElems(g); - // now give the g itself a new id - g.id = getNextId(); - - current_layer.appendChild(g); - - // change image href vals if possible -// $(svgcontent).find('image').each(function() { -// var image = this; -// preventClickDefault(image); -// var val = this.getAttributeNS(xlinkns, "href"); -// if(val.indexOf('data:') === 0) { -// // Check if an SVG-edit data URI -// var m = val.match(/svgedit_url=(.*?);/); -// if(m) { -// var url = decodeURIComponent(m[1]); -// $(new Image()).load(function() { -// image.setAttributeNS(xlinkns,'xlink:href',url); -// }).attr('src',url); -// } -// } -// // Add to encodableImages if it loads -// canvas.embedImage(val); -// }); - - - // recalculate dimensions on the top-level children so that unnecessary transforms - // are removed - walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}}); - - - batchCmd.addSubCommand(new InsertElementCommand(svgcontent)); - - // reset zoom - TODO: why? -// current_zoom = 1; - - // identify layers -// identifyLayers(); - - // reset transform lists - svgTransformLists = {}; - clearSelection(); - - addCommandToHistory(batchCmd); call("changed", [svgcontent]); } catch(e) { console.log(e); @@ -8640,9 +8694,13 @@ this.setConfig = function(opts) { } // Function: getDocumentTitle -// Returns the current document title or an empty string if not found -this.getDocumentTitle = function() { - var childs = svgcontent.childNodes; +// Returns the current group/SVG's title contents +this.getTitle = function(elem) { + elem = elem || selectedElements[0]; + if(!elem) return; + elem = $(elem).data('gsvg') || elem; + + var childs = elem.childNodes; for (var i=0; i + if(!chtlist) continue; + if (glist.numberOfItems) { // TODO: if the group's transform is just a rotate, we can always transfer the // rotate() down to the children (collapsing consecutive rotates and factoring