diff --git a/editor/svg-editor.css b/editor/svg-editor.css index 27a24092..c33f1d72 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -141,6 +141,10 @@ div.color_block { vertical-align: 12px; } +#svg_editor #multiselected_panel .selected_tool { + vertical-align: 12px; +} + #svg_editor #text_panel .text_tool { vertical-align: 12px; } diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 4869e32f..0a63fcd8 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -88,10 +88,16 @@ Left Center Right - | Top Middle Bottom + relative to: +
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 7eb1d36a..408ecc85 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -543,26 +543,26 @@ function svg_edit_setup() { var clickClone = function(){ svgCanvas.cloneSelectedElements(); }; - + var clickAlignLeft = function(){ - svgCanvas.alignSelectedElements('l'); + svgCanvas.alignSelectedElements('l', $('#align_relative_to option:selected').val() ); }; var clickAlignCenter = function(){ - svgCanvas.alignSelectedElements('c'); + svgCanvas.alignSelectedElements('c', $('#align_relative_to option:selected').val() ); }; var clickAlignRight = function(){ - svgCanvas.alignSelectedElements('r'); + svgCanvas.alignSelectedElements('r', $('#align_relative_to option:selected').val() ); }; var clickAlignTop = function(){ - svgCanvas.alignSelectedElements('t'); + svgCanvas.alignSelectedElements('t', $('#align_relative_to option:selected').val() ); }; var clickAlignMiddle = function(){ - svgCanvas.alignSelectedElements('m'); + svgCanvas.alignSelectedElements('m', $('#align_relative_to option:selected').val() ); }; var clickAlignBottom = function(){ - svgCanvas.alignSelectedElements('b'); + svgCanvas.alignSelectedElements('b', $('#align_relative_to option:selected').val() ); }; - + var showSourceEditor = function(){ if (editingsource) return; editingsource = true; diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index c3e96f84..280c99e4 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -2681,16 +2681,17 @@ function SvgCanvas(c) }; // aligns selected elements (type is a char - see switch below for explanation) - this.alignSelectedElements = function(type) { + // relative_to can be "selected", "largest", "smallest", "page" + this.alignSelectedElements = function(type, relative_to) { var bboxes = [], angles = []; var minx = Number.MAX_VALUE, maxx = Number.MIN_VALUE, miny = Number.MAX_VALUE, maxy = Number.MIN_VALUE; + var curwidth = Number.MIN_VALUE, curheight = Number.MIN_VALUE; var len = selectedElements.length; if (!len) return; for (var i = 0; i < len; ++i) { if (selectedElements[i] == null) break; var elem = selectedElements[i]; bboxes[i] = this.getBBox(elem); - // TODO: could make the following code block as part of getBBox() and add a parameter // to that function // if element is rotated, get angle and rotate the 4 corners of the bbox and get @@ -2703,11 +2704,11 @@ function SvgCanvas(c) cy = bboxes[i].y + bboxes[i].height/2; var pts = [ [bboxes[i].x - cx, bboxes[i].y - cy], [bboxes[i].x + bboxes[i].width - cx, bboxes[i].y - cy], - [bboxes[i].x + bboxes[i].width - cx, bboxes[i].y + bboxes[i].height - cy], + [bboxes[i].x + bboxes[i].width - cx, bboxes[i].y + bboxes[i].height - cy], [bboxes[i].x - cx, bboxes[i].y + bboxes[i].height - cy] ]; var j = 4; while (j--) { - var x = pts[j][0], + var x = pts[j][0], y = pts[j][1], r = Math.sqrt( x*x + y*y ); var theta = Math.atan2(y,x) + angles[i]; @@ -2728,12 +2729,45 @@ function SvgCanvas(c) } // now bbox is axis-aligned and handles rotation - if (bboxes[i].x < minx) minx = bboxes[i].x; - if (bboxes[i].y < miny) miny = bboxes[i].y; - if (bboxes[i].x+bboxes[i].width > maxx) maxx = bboxes[i].x+bboxes[i].width; - if (bboxes[i].y+bboxes[i].height > maxy) maxy = bboxes[i].y+bboxes[i].height; + switch (relative_to) { + case 'smallest': + if ( (type == 'l' || type == 'c' || type == 'r') && (curwidth == Number.MIN_VALUE || curwidth > bboxes[i].width) || + (type == 't' || type == 'm' || type == 'b') && (curheight == Number.MIN_VALUE || curheight > bboxes[i].height) ) { + minx = bboxes[i].x; + miny = bboxes[i].y; + maxx = bboxes[i].x + bboxes[i].width; + maxy = bboxes[i].y + bboxes[i].height; + curwidth = bboxes[i].width; + curheight = bboxes[i].height; + } + break; + case 'largest': + if ( (type == 'l' || type == 'c' || type == 'r') && (curwidth == Number.MIN_VALUE || curwidth < bboxes[i].width) || + (type == 't' || type == 'm' || type == 'b') && (curheight == Number.MIN_VALUE || curheight < bboxes[i].height) ) { + minx = bboxes[i].x; + miny = bboxes[i].y; + maxx = bboxes[i].x + bboxes[i].width; + maxy = bboxes[i].y + bboxes[i].height; + curwidth = bboxes[i].width; + curheight = bboxes[i].height; + } + break; + default: // 'selected' + if (bboxes[i].x < minx) minx = bboxes[i].x; + if (bboxes[i].y < miny) miny = bboxes[i].y; + if (bboxes[i].x + bboxes[i].width > maxx) maxx = bboxes[i].x + bboxes[i].width; + if (bboxes[i].y + bboxes[i].height > maxy) maxy = bboxes[i].y + bboxes[i].height; + break; + } } // loop for each element to find the bbox and adjust min/max - + + if (relative_to == 'page') { + minx = 0; + miny = 0; + maxx = svgroot.getAttribute('width'); + maxy = svgroot.getAttribute('height'); + } + var dx = new Array(len); var dy = new Array(len); for (var i = 0; i < len; ++i) {