Fix Issue 101: Minimally size the bounding box for polylines, polygons, paths.
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@416 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
c2e0387465
commit
0bb7c15fb0
|
@ -794,13 +794,13 @@ function SvgCanvas(c)
|
||||||
|
|
||||||
switch (selected.tagName)
|
switch (selected.tagName)
|
||||||
{
|
{
|
||||||
// NOTE: there's no way to create an actual polygon element except by editing source
|
// NOTE: at the moment, there's no way to create an actual polygon element except by
|
||||||
// or importing from somewhere else
|
// editing source or importing from somewhere else but we'll cover it here anyway
|
||||||
|
// polygon is handled just like polyline
|
||||||
case "polygon":
|
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 points from the polygon/polyline, adjust it and write back the new points
|
||||||
// but first, save the old path
|
// but first, save the old points
|
||||||
changes["points"] = selected.getAttribute("points");
|
changes["points"] = selected.getAttribute("points");
|
||||||
var list = selected.points;
|
var list = selected.points;
|
||||||
var len = list.numberOfItems;
|
var len = list.numberOfItems;
|
||||||
|
@ -808,7 +808,6 @@ function SvgCanvas(c)
|
||||||
for (var i = 0; i < len; ++i) {
|
for (var i = 0; i < len; ++i) {
|
||||||
var pt = list.getItem(i);
|
var pt = list.getItem(i);
|
||||||
var x = remapx(pt.x), y = remapy(pt.y);
|
var x = remapx(pt.x), y = remapy(pt.y);
|
||||||
// we only need to scale the relative coordinates (no need to translate)
|
|
||||||
newpoints += x + "," + y + " ";
|
newpoints += x + "," + y + " ";
|
||||||
}
|
}
|
||||||
selected.setAttributeNS(null, "points", newpoints);
|
selected.setAttributeNS(null, "points", newpoints);
|
||||||
|
@ -2208,7 +2207,7 @@ function SvgCanvas(c)
|
||||||
var tx = Math.atan( -b * Math.tan(angle)/a ),
|
var tx = Math.atan( -b * Math.tan(angle)/a ),
|
||||||
ty = Math.atan( b * (1.0 / Math.tan(angle))/a );
|
ty = Math.atan( b * (1.0 / Math.tan(angle))/a );
|
||||||
|
|
||||||
var X = [], Y = [];
|
var X = new Array(2), Y = new Array(2);
|
||||||
|
|
||||||
X[0] = h + a*Math.cos(tx)*Math.cos(angle) - b*Math.sin(tx)*Math.sin(angle);
|
X[0] = h + a*Math.cos(tx)*Math.cos(angle) - b*Math.sin(tx)*Math.sin(angle);
|
||||||
Y[0] = k + b*Math.sin(ty)*Math.cos(angle) + a*Math.cos(ty)*Math.sin(angle);
|
Y[0] = k + b*Math.sin(ty)*Math.cos(angle) + a*Math.cos(ty)*Math.sin(angle);
|
||||||
|
@ -2229,8 +2228,101 @@ function SvgCanvas(c)
|
||||||
bbox.height = parseInt( Y[1] - Y[0] );
|
bbox.height = parseInt( Y[1] - Y[0] );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO: handle path, polyline, polygon here by iterating through all points
|
case "polygon":
|
||||||
|
case "polyline":
|
||||||
|
var MINX = Number.MAX_VALUE, MINY = Number.MAX_VALUE,
|
||||||
|
MAXX = Number.MIN_VALUE, MAXY = Number.MIN_VALUE;
|
||||||
|
// calculate the cx,cy (pull from transform attr?)
|
||||||
|
var cx = bbox.x + bbox.width/2,
|
||||||
|
cy = bbox.y + bbox.height/2;
|
||||||
|
console.log('cx=' + cx + ', cy=' + cy);
|
||||||
|
var list = selected.points;
|
||||||
|
var i = list.numberOfItems;
|
||||||
|
while (i--) {
|
||||||
|
var pt = list.getItem(i);
|
||||||
|
var dx = pt.x - cx, dy = pt.y - cy;
|
||||||
|
var r = Math.sqrt( dx*dx + dy*dy );
|
||||||
|
var theta = angle + Math.atan2(dy,dx);
|
||||||
|
var x = r * Math.cos(theta), y = r * Math.sin(theta);
|
||||||
|
if (MINX > x) { MINX = x; }
|
||||||
|
if (MINY > y) { MINY = y; }
|
||||||
|
if (MAXX < x) { MAXX = x; }
|
||||||
|
if (MAXY < y) { MAXY = y; }
|
||||||
|
}
|
||||||
|
bbox.x = parseInt(cx + MINX);
|
||||||
|
bbox.y = parseInt(cy + MINY);
|
||||||
|
bbox.width = parseInt(MAXX-MINX);
|
||||||
|
bbox.height = parseInt(MAXY-MINY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "path":
|
||||||
|
var MINX = Number.MAX_VALUE, MINY = Number.MAX_VALUE,
|
||||||
|
MAXX = Number.MIN_VALUE, MAXY = Number.MIN_VALUE;
|
||||||
|
// calculate the cx,cy (pull from transform attr?)
|
||||||
|
var cx = bbox.x + bbox.width/2,
|
||||||
|
cy = bbox.y + bbox.height/2;
|
||||||
|
var segList = selected.pathSegList;
|
||||||
|
var len = segList.numberOfItems;
|
||||||
|
var curx = 0, cury = 0;
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
var seg = segList.getItem(i);
|
||||||
|
// if these properties are not in the segment, set them to zero
|
||||||
|
var x = seg.x || 0,
|
||||||
|
y = seg.y || 0;
|
||||||
|
|
||||||
|
var type = seg.pathSegType;
|
||||||
|
switch (type) {
|
||||||
|
case 1: // z,Z closepath (Z/z)
|
||||||
|
x = curx;
|
||||||
|
y = cury;
|
||||||
|
break;
|
||||||
|
// turn this into a relative segment then fall through
|
||||||
|
case 2: // absolute move (M)
|
||||||
|
case 4: // absolute line (L)
|
||||||
|
case 6: // absolute cubic (C)
|
||||||
|
case 8: // absolute quad (Q)
|
||||||
|
case 10: // absolute elliptical arc (A)
|
||||||
|
case 12: // absolute horizontal line (H)
|
||||||
|
case 14: // absolute vertical line (V)
|
||||||
|
case 16: // absolute smooth cubic (S)
|
||||||
|
case 18: // absolute smooth quad (T)
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
break;
|
||||||
|
case 3: // relative move (m)
|
||||||
|
case 5: // relative line (l)
|
||||||
|
case 7: // relative cubic (c)
|
||||||
|
case 9: // relative quad (q)
|
||||||
|
case 13: // relative horizontal line (h)
|
||||||
|
case 15: // relative vertical line (v)
|
||||||
|
case 19: // relative smooth quad (t)
|
||||||
|
case 11: // relative elliptical arc (a)
|
||||||
|
case 17: // relative smooth cubic (s)
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
x = curx;
|
||||||
|
y = cury;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dx = x - cx, dy = y - cy;
|
||||||
|
var r = Math.sqrt( dx*dx + dy*dy );
|
||||||
|
var theta = angle + Math.atan2(dy,dx);
|
||||||
|
x = r * Math.cos(theta);
|
||||||
|
y = r * Math.sin(theta);
|
||||||
|
if (MINX > x) { MINX = x; }
|
||||||
|
if (MINY > y) { MINY = y; }
|
||||||
|
if (MAXX < x) { MAXX = x; }
|
||||||
|
if (MAXY < y) { MAXY = y; }
|
||||||
|
}
|
||||||
|
bbox.x = parseInt(cx + MINX);
|
||||||
|
bbox.y = parseInt(cy + MINY);
|
||||||
|
bbox.width = parseInt(MAXX-MINX);
|
||||||
|
bbox.height = parseInt(MAXY-MINY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: handle path here by iterating through all points
|
||||||
// transforming each point into the rotated coordinate system and tracking
|
// transforming each point into the rotated coordinate system and tracking
|
||||||
// the MINX, MAXX, MINY, MAXY
|
// the MINX, MAXX, MINY, MAXY
|
||||||
|
|
||||||
|
@ -2251,8 +2343,8 @@ function SvgCanvas(c)
|
||||||
if (MAXX < x) { MAXX = x; }
|
if (MAXX < x) { MAXX = x; }
|
||||||
if (MAXY < y) { MAXY = y; }
|
if (MAXY < y) { MAXY = y; }
|
||||||
}
|
}
|
||||||
bbox.x = cx + parseInt(MINX);
|
bbox.x = parseInt(cx + MINX);
|
||||||
bbox.y = cy + parseInt(MINY);
|
bbox.y = parseInt(cy + MINY);
|
||||||
bbox.width = parseInt(MAXX-MINX);
|
bbox.width = parseInt(MAXX-MINX);
|
||||||
bbox.height = parseInt(MAXY-MINY);
|
bbox.height = parseInt(MAXY-MINY);
|
||||||
break;
|
break;
|
||||||
|
@ -2279,7 +2371,9 @@ function SvgCanvas(c)
|
||||||
|
|
||||||
this.setRotationAngle = function(val) {
|
this.setRotationAngle = function(val) {
|
||||||
var elem = selectedElements[0];
|
var elem = selectedElements[0];
|
||||||
var bbox = this.getBBox(elem);
|
// we use the actual element's bbox (not the calculated one) since the
|
||||||
|
// calculated bbox's center can change depending on the angle
|
||||||
|
var bbox = elem.getBBox(); //this.getBBox(elem);
|
||||||
var rotate = "rotate(" + val + " " +
|
var rotate = "rotate(" + val + " " +
|
||||||
(bbox.x+bbox.width/2) + "," +
|
(bbox.x+bbox.width/2) + "," +
|
||||||
(bbox.y+bbox.height/2) + ")";
|
(bbox.y+bbox.height/2) + ")";
|
||||||
|
|
Loading…
Reference in New Issue