Fix resizing of arbitrary paths (for all segment types). Add polygon to whitelist.

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@384 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Jeff Schiller 2009-08-15 04:37:08 +00:00
parent 93611c6c71
commit c83d515fe9
2 changed files with 97 additions and 23 deletions

View File

@ -156,6 +156,7 @@ function svg_edit_setup() {
$('#line_panel').hide(); $('#line_panel').hide();
$('#text_panel').hide(); $('#text_panel').hide();
if (elem != null) { if (elem != null) {
// TODO: get element's rotation value and set the angle spinner
$('#selected_panel').show(); $('#selected_panel').show();
// update contextual tools here // update contextual tools here
switch(elem.tagName) { switch(elem.tagName) {

View File

@ -17,6 +17,7 @@ var svgWhiteList = {
"line": ["fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform", "x1", "x2", "y1", "y2"], "line": ["fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform", "x1", "x2", "y1", "y2"],
"linearGradient": ["id", "gradientTransform", "gradientUnits", "spreadMethod", "x1", "x2", "y1", "y2"], "linearGradient": ["id", "gradientTransform", "gradientUnits", "spreadMethod", "x1", "x2", "y1", "y2"],
"path": ["d", "fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform"], "path": ["d", "fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform"],
"polygon": ["id", "fill", "fill-opacity", "points", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform"],
"polyline": ["id", "points", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform"], "polyline": ["id", "points", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform"],
"radialGradient": ["id", "cx", "cy", "fx", "fy", "gradientTransform", "gradientUnits", "r", "spreadMethod"], "radialGradient": ["id", "cx", "cy", "fx", "fy", "gradientTransform", "gradientUnits", "r", "spreadMethod"],
"rect": ["fill", "fill-opacity", "height", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform", "width", "x", "y"], "rect": ["fill", "fill-opacity", "height", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "transform", "width", "x", "y"],
@ -702,6 +703,11 @@ function SvgCanvas(c)
} }
}; };
// this is how we map paths to our preferred relative segment types
var pathMap = [ 0, 'z', 'm', 'm', 'l', 'l', 'c', 'c', 'q', 'q', 'a', 'a',
'l', 'l', 'l', 'l', // TODO: be less lazy below and map them to h and v
's', 's', 't', 't' ];
// this function returns the command which resulted from th selected change // this function returns the command which resulted from th selected change
var recalculateSelectedDimensions = function(i) { var recalculateSelectedDimensions = function(i) {
var selected = selectedElements[i]; var selected = selectedElements[i];
@ -717,10 +723,10 @@ function SvgCanvas(c)
// after this point, we have some change to this element // after this point, we have some change to this element
var remapx = function(x) {return ((x-box.x)/box.width)*selectedBBox.width + selectedBBox.x;} var remapx = function(x) {return parseInt(((x-box.x)/box.width)*selectedBBox.width + selectedBBox.x);}
var remapy = function(y) {return ((y-box.y)/box.height)*selectedBBox.height + selectedBBox.y;} var remapy = function(y) {return parseInt(((y-box.y)/box.height)*selectedBBox.height + selectedBBox.y);}
var scalew = function(w) {return w*selectedBBox.width/box.width;} var scalew = function(w) {return parseInt(w*selectedBBox.width/box.width);}
var scaleh = function(h) {return h*selectedBBox.height/box.height;} var scaleh = function(h) {return parseInt(h*selectedBBox.height/box.height);}
var changes = {}; var changes = {};
@ -731,6 +737,10 @@ function SvgCanvas(c)
selected.removeAttribute("transform"); selected.removeAttribute("transform");
switch (selected.tagName) switch (selected.tagName)
{ {
// NOTE: there's no way to create an actual polygon element except by editing source
// or importing from somewhere else
case "polygon":
// polygon is handled identically as polyline
case "polyline": case "polyline":
// extract the x,y from the path, adjust it and write back the new path // extract the x,y from the path, adjust it and write back the new path
// but first, save the old path // but first, save the old path
@ -756,25 +766,88 @@ function SvgCanvas(c)
var segList = selected.pathSegList; var segList = selected.pathSegList;
var len = segList.numberOfItems; var len = segList.numberOfItems;
for (var i = 1; i < len; ++i) { for (var i = 1; i < len; ++i) {
var l = segList.getItem(i); var seg = segList.getItem(i);
var x = l.x, y = l.y; // if these properties are not in the segment, set them to zero
// polys can now be closed, skip Z segments var x = seg.x || 0,
if (l.pathSegType == 1) { y = seg.y || 0,
newd += "z"; x1 = seg.x1 || 0,
continue; y1 = seg.y1 || 0,
} x2 = seg.x2 || 0,
// webkit browsers normalize things and this becomes an absolute y2 = seg.y2 || 0;
// line segment! we need to turn this back into a rel line segment
// see https://bugs.webkit.org/show_bug.cgi?id=26487 // This will let us drag/resize any path (currently we can only
if (l.pathSegType == 4) { // drag/resize paths that contain line segments)
x -= curx; // Webkit browsers normalize things and all relative segments becomes absolute
y -= cury; // We turn them back into relative segments. see https://bugs.webkit.org/show_bug.cgi?id=26487
curx += x; var type = seg.pathSegType;
cury += y; switch (type) {
} case 1: // z,Z closepath (Z/z)
// we only need to scale the relative coordinates (no need to translate) newd += "z";
newd += " l" + scalew(x) + "," + scaleh(y); continue;
} // turn this into a relative segment by falling through
case 2: // absolute move (M)
case 4: // absolute line (L)
case 12: // absolute horizontal line (H)
case 14: // absolute vertical line (V)
case 18: // absolute smooth quad (T)
x -= curx;
y -= cury;
case 3: // relative move (m)
case 5: // relative line (l)
case 13: // relative horizontal line (h)
case 15: // relative vertical line (v)
case 19: // relative smooth quad (t)
x = scalew(x);
y = scaleh(y);
curx += x;
cury += y;
newd += [" ", pathMap[type], x, ",", y].join('');
break;
case 6: // absolute cubic (C)
x -= curx; x1 -= curx; x2 -= curx;
y -= cury; y1 -= cury; y2 -= cury;
case 7: // relative cubic (c)
x = scalew(x);
y = scaleh(y);
curx += x;
cury += y;
newd += [" c", scalew(x1), ",", scaleh(y1), " ", scalew(x2), ",", scaleh(y2),
" ", x, ",", y].join('');
break;
case 8: // absolute quad (Q)
x -= curx; x1 -= curx;
y -= cury; y1 -= cury;
case 9: // relative quad (q)
x = scalew(x);
y = scaleh(y);
curx += x;
cury += y;
newd += [" q", scalew(x1), ",", scaleh(y1), " ", x, ",", y].join('');
break;
case 10: // absolute elliptical arc (A)
x -= curx;
y -= cury;
case 11: // relative elliptical arc (a)
x = scalew(x);
y = scaleh(y);
curx += x;
cury += y;
newd += [ "a", scalew(seg.r1), ",", scaleh(seg.r2), " ", seg.angle, " ",
(seg.largeArcFlag ? 1 : 0), " ", (seg.sweepFlag ? 1 : 0), " ",
x, ",", y ].join('')
break;
case 16: // absolute smooth cubic (S)
x -= curx; x2 -= curx;
y -= cury; y2 -= cury;
case 17: // relative smooth cubic (s)
x = scalew(x);
y = scaleh(y);
curx += x;
cury += y;
newd += [" s", scalew(x2), ",", scaleh(y2), " ", x, ",", y].join('');
break;
} // switch on path segment type
} // for each segment
selected.setAttributeNS(null, "d", newd); selected.setAttributeNS(null, "d", newd);
break; break;
case "line": case "line":