transformlist branch: Can resize groups as long as they are not rotated. Rotating groups still broken. Ungrouping still broken

git-svn-id: http://svg-edit.googlecode.com/svn/branches/transformlist@923 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Jeff Schiller 2009-11-10 07:15:29 +00:00
parent 9cb650119f
commit f603b01efc
1 changed files with 63 additions and 51 deletions

View File

@ -1,11 +1,7 @@
/* /*
TODOs for TransformList: TODOs for TransformList:
* Fix rotation of groups (rotate being prepended) * Fix rotating of resized groups (need to re-center?)
* See if we can completely eliminate translates on groups (currently flattening to one)
* Flattening adjacent scale transform sets on groups
* Fix bounding box of groups with rotated children
* Fix resizing/rotating of groups (pummel the transforms down to the children?)
* Ensure resizing in negative direction works (nope! broken!) * Ensure resizing in negative direction works (nope! broken!)
* Ensure ungrouping works (surely broken) * Ensure ungrouping works (surely broken)
* Ensure undo still works properly (nope! broken!) * Ensure undo still works properly (nope! broken!)
@ -1383,7 +1379,8 @@ function BatchCommand(text) {
// always remove translates by transferring them down to the children // always remove translates by transferring them down to the children
// otherwise just reduce adjacent scales // otherwise just reduce adjacent scales
// The first pass is to collapse all translates // The first pass is to collapse all adjacent translates and push
// them down to the children
var n = tlist.numberOfItems; var n = tlist.numberOfItems;
while (n--) { while (n--) {
var xform = tlist.getItem(n); var xform = tlist.getItem(n);
@ -1401,21 +1398,8 @@ function BatchCommand(text) {
tlist.removeItem(n); tlist.removeItem(n);
} }
// now restore just the one translate // now restore just the one translate
// its matrix before transferring down
if (tx != 0 || ty != 0) { if (tx != 0 || ty != 0) {
var newxlate = svgroot.createSVGTransform(); // we pass the translates down to the individual children
newxlate.setTranslate(tx,ty);
tlist.insertItemBefore(newxlate, 0);
// TODO: can we pass the translates down to the individual children?
/*
// get the matrix of the remaining transformlist
var mat = svgroot.createSVGMatrix();
var m = tlist.numberOfItems;
while (m--) {
mat = matrixMultiply(tlist.getItem(m).matrix, mat);
}
mat = mat.inverse();
var mv = transformPoint(tx,ty,mat);
var children = selected.childNodes; var children = selected.childNodes;
var c = children.length; var c = children.length;
while (c--) { while (c--) {
@ -1423,56 +1407,84 @@ function BatchCommand(text) {
if (child.nodeType == 1) { if (child.nodeType == 1) {
var childTlist = canvas.getTransformList(child); var childTlist = canvas.getTransformList(child);
var newxlate = svgroot.createSVGTransform(); var newxlate = svgroot.createSVGTransform();
newxlate.setTranslate(mv.x,mv.y); newxlate.setTranslate(tx,ty);
childTlist.insertItemBefore(newxlate, 0); childTlist.insertItemBefore(newxlate, 0);
batchCmd.addSubCommand( recalculateDimensions(child) ); batchCmd.addSubCommand( recalculateDimensions(child) );
} }
} }
*/
} }
// The second pass is to find all adjacent transform sets of the form: // The second pass is to find all adjacent transform sets of the form:
// translate(tx,ty) scale(sx,sy) translate(-tx,-ty) and collapse them // translate(tx,ty) scale(sx,sy) translate(-tx,-ty) and collapse them by
tx = 0; // applying the translates to the children and accumulating the scale factors
ty = 0; var mat = svgroot.createSVGMatrix();
var bGotOffset = false;
n = tlist.numberOfItems; n = tlist.numberOfItems;
while (n--) { while (n--) {
var xform = tlist.getItem(n); var xform = tlist.getItem(n);
if (!xform || xform.type != 3) { // we stop as soon as we encounter a rotate
continue; if (xform.type == 4) {
// update the frame of reference
mat = matrixMultiply(mat, xform.matrix);
break;
} }
// if it's a translate we push it to the children
else if (xform.type == 2) {
// get the centroid of scaling and determine the net translation for this scale
var tobj = transformToObj(xform);
var sobj = transformToObj(xform); var t = transformPoint(tobj.tx, tobj.ty, mat.inverse());
sx *= sobj.sx;
sy *= sobj.sy; // we pass the translates down to the individual children
if (!bGotOffset) { var children = selected.childNodes;
var tobj = transformToObj(tlist.getItem(n-1)); var c = children.length;
tx = tobj.tx; while (c--) {
ty = tobj.ty; var child = children.item(c);
bGotOffset = true; if (child.nodeType == 1) {
var childTlist = canvas.getTransformList(child);
var newxlate = svgroot.createSVGTransform();
newxlate.setTranslate(t.x, t.y);
childTlist.insertItemBefore(newxlate, 0);
batchCmd.addSubCommand( recalculateDimensions(child) );
}
}
tlist.removeItem(n);
}
// if it's a scale, we accumulate it
else if (xform.type == 3) {
// update the frame of reference
mat = matrixMultiply(mat, xform.matrix);
// accumulate the scale values
var sobj = transformToObj(xform);
sx *= sobj.sx;
sy *= sobj.sy;
tlist.removeItem(n);
} }
// remove the scale and translates from the group
tlist.removeItem(n+1);
tlist.removeItem(n);
tlist.removeItem(n-1);
// decrement one more so that we're not off the end of the transformlist
// after removing three transforms above
n--;
} }
// now restore just the one scale and its offset translates // now restore just the one scale
if (sx != 1 || sy != 1) { if (sx != 1 || sy != 1) {
var newscale = svgroot.createSVGTransform(), var newscale = svgroot.createSVGTransform();
offset_p = svgroot.createSVGTransform(),
offset_n = svgroot.createSVGTransform();
offset_n.setTranslate(-tx,-ty);
offset_p.setTranslate(tx,ty);
newscale.setScale(sx,sy); newscale.setScale(sx,sy);
tlist.appendItem(offset_p);
tlist.appendItem(newscale); tlist.appendItem(newscale);
tlist.appendItem(offset_n);
} }
// TODO: if we have a rotate, we need to update its center
// now loop through the other transforms and adjust accordingly
/*
var newBox = canvas.getBBox(selected);
for ( var j = 0; j < tlist.numberOfItems; ++j) {
var changed_xform = tlist.getItem(j);
switch (changed_xform.type) {
case 4: // rotate
var newrot = svgroot.createSVGTransform();
newrot.setRotate(changed_xform.angle, newcenter.x, newcenter.y);
tlist.replaceItem(newrot, j);
break;
}
}
*/
} }
// else, it's a non-group // else, it's a non-group
else { else {