transformlist branch: more refactoring. groups can be rotated, translated, resized. still buggy when resizing rotated groups but checking it in anyway. ungrouping still surely broken

git-svn-id: http://svg-edit.googlecode.com/svn/branches/transformlist@932 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Jeff Schiller 2009-11-12 05:02:11 +00:00
parent 7c8fafa9ee
commit 3924530ea3
1 changed files with 51 additions and 59 deletions

View File

@ -1279,6 +1279,10 @@ function BatchCommand(text) {
var truePathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a', var truePathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
'H', 'h', 'V', 'v', 'S', 's', 'T', 't']; 'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
var logMatrix = function(m) {
console.log([m.a,m.b,m.c,m.d,m.e,m.f]);
};
// this function returns the command which resulted from the selected change // this function returns the command which resulted from the selected change
// TODO: use suspendRedraw() and unsuspendRedraw() around this function // TODO: use suspendRedraw() and unsuspendRedraw() around this function
var recalculateDimensions = function(selected) { var recalculateDimensions = function(selected) {
@ -1383,52 +1387,41 @@ function BatchCommand(text) {
var box = canvas.getBBox(selected); var box = canvas.getBBox(selected);
var origcenter = {x: (box.x+box.width/2), y: (box.y+box.height/2)}; var origcenter = {x: (box.x+box.width/2), y: (box.y+box.height/2)};
var newcenter = {x: origcenter.x, y: origcenter.y}; var newcenter = {x: origcenter.x, y: origcenter.y};
var currentMatrix = {a:1, b:0, c:0, d:1, e:0, f:0};
var tx = 0.0, ty = 0.0, sx = 1.0, sy = 1.0, r = 0.0; var tx = 0.0, ty = 0.0, sx = 1.0, sy = 1.0, r = 0.0;
// if it's a group, we have special reduction loops to flatten transforms // if it's a group, we have special reduction loops to flatten transforms
if (selected.tagName == "g") { if (selected.tagName == "g") {
// loop through transforms and accumulate translation and scaling // loop through transforms and accumulate translation and scaling
var mat = svgroot.createSVGMatrix(); var mat = svgroot.createSVGMatrix();
var bFoundRotate = false;
n = tlist.numberOfItems; n = tlist.numberOfItems;
while (n--) { while (n--) {
var xform = tlist.getItem(n); var xform = tlist.getItem(n);
if (xform.type == 4) {
// update the frame of reference
mat = matrixMultiply(xform.matrix, mat);
bFoundRotate = true;
// break;
}
// accumulate the transformed translation
else if (xform.type == 2) {
// get the centroid of scaling and determine the net translation for this scale
var tobj = transformToObj(xform);
if (bFoundRotate && false) {
tx += tobj.tx;
ty += tobj.ty;
}
else {
var t = transformPoint(tobj.tx, tobj.ty, mat.inverse());
// accumulate translation
tx += t.x;
ty += t.y;
}
tlist.removeItem(n);
}
// if it's a scale, we accumulate it // if it's a scale, we accumulate it
else if (xform.type == 3) { if (xform.type == 3) {
// update the frame of reference // update the frame of reference
mat = matrixMultiply(mat, xform.matrix); mat = matrixMultiply(xform.matrix, mat);
// accumulate the scale values // accumulate the scale values
var sobj = transformToObj(xform); var sobj = transformToObj(xform);
sx *= sobj.sx; sx *= sobj.sx;
sy *= sobj.sy; sy *= sobj.sy;
tlist.removeItem(n);
}
// if it's a rotation, adjust the frame of reference
else if (xform.type == 4) {
// mat = matrixMultiply(xform.matrix, mat);
r = xform.angle;
tlist.removeItem(n);
}
// accumulate the transformed translation
else if (xform.type == 2) {
// determine the translation based on the accumulated transformation thus far
var tobj = transformToObj(xform);
var t = transformPoint(tobj.tx, tobj.ty, mat.inverse());
// accumulate translation values
tx += t.x;
ty += t.y;
tlist.removeItem(n); tlist.removeItem(n);
} }
} }
@ -1450,29 +1443,26 @@ function BatchCommand(text) {
} }
} }
// now apply only one scale // now append the single scale to the end of this group's tlist
// NOTE: we can't force this down to the children because they
// might be rotated on a different frame of reference than the scale
if (sx != 1 || sy != 1) { if (sx != 1 || sy != 1) {
var newscale = svgroot.createSVGTransform(); var newscale = svgroot.createSVGTransform();
newscale.setScale(sx,sy); newscale.setScale(sx,sy);
tlist.appendItem(newscale); tlist.appendItem(newscale);
} }
// TODO: if we have a rotate, we need to update its center and if (r != 0.0) {
// adjust the transforms again // get new bbox
/* var box = canvas.getBBox(selected);
var newBox = canvas.getBBox(selected); // transform the center point by any remaining scale transforms
for ( var j = 0; j < tlist.numberOfItems; ++j) { var cx = (box.x+box.width/2)*sx,
var changed_xform = tlist.getItem(j); cy = (box.y+box.height/2)*sy;
switch (changed_xform.type) {
case 4: // rotate
var newrot = svgroot.createSVGTransform(); var newrot = svgroot.createSVGTransform();
newrot.setRotate(changed_xform.angle, newcenter.x, newcenter.y); newrot.setRotate(r,cx,cy);
tlist.replaceItem(newrot, j); tlist.insertItemBefore(newrot,0);
break;
} }
} }
*/
}
// else, it's a non-group // else, it's a non-group
else { else {
// This pass loop in reverse order and removes any translates or scales. // This pass loop in reverse order and removes any translates or scales.
@ -1543,6 +1533,8 @@ function BatchCommand(text) {
switch (selected.tagName) switch (selected.tagName)
{ {
case "g":
break;
case "line": case "line":
var pt1 = remap(changes["x1"],changes["y1"]), var pt1 = remap(changes["x1"],changes["y1"]),
pt2 = remap(changes["x2"],changes["y2"]); pt2 = remap(changes["x2"],changes["y2"]);
@ -2039,9 +2031,9 @@ function BatchCommand(text) {
sx = b / Math.sin(rad); sx = b / Math.sin(rad);
sy = -c / Math.sin(rad); sy = -c / Math.sin(rad);
} }
else { // in the case of no rotation, scales are simply a,d else {
sx = a; sx = a / Math.cos(rad);
sy = d; sy = d / Math.cos(rad);
} }
// scale // scale
@ -4884,24 +4876,24 @@ function BatchCommand(text) {
var bbox = elem.getBBox(); var bbox = elem.getBBox();
var cx = round(bbox.x+bbox.width/2), cy = round(bbox.y+bbox.height/2); var cx = round(bbox.x+bbox.width/2), cy = round(bbox.y+bbox.height/2);
var tlist = canvas.getTransformList(elem); var tlist = canvas.getTransformList(elem);
var rotIndex = -1; var rotIndex = 0;
// find the index of the rotation trnasform // find the index of the rotation transform
var n = tlist.numberOfItems; var n = tlist.numberOfItems;
while (n--) { while (n--) {
var xform = tlist.getItem(n); var xform = tlist.getItem(n);
if (xform.type == 4) { if (xform.type == 4) {
rotIndex = n; rotIndex = n;
tlist.removeItem(n);
break; break;
} }
} }
// if we are not rotated yet, insert a dummy xform // if we are not rotated yet, insert a dummy xform
if (rotIndex == -1) {
tlist.insertItemBefore(svgroot.createSVGTransform(), 0);
rotIndex = 0;
}
var newrot = tlist.getItem(rotIndex); var m = elem.getCTM();
newrot.setRotate(val, cx, cy); var center = transformPoint(cx,cy,m);
var newrot = svgroot.createSVGTransform();
newrot.setRotate(val, center.x, center.y);
tlist.insertItemBefore(newrot, rotIndex);
// TODO: remove this seperate chunk of code where we replace the rotation transform // TODO: remove this seperate chunk of code where we replace the rotation transform
// because calling setRotate() above changes the live transform in the list // because calling setRotate() above changes the live transform in the list