reworked transformation matrix operations with drag and drop

This commit is contained in:
Eric Rowell 2012-03-24 20:52:17 -07:00
parent 1fa41e6692
commit f312c0cf9d
8 changed files with 171 additions and 71 deletions

95
dist/kinetic-core.js vendored
View File

@ -52,10 +52,6 @@ Kinetic.GlobalObject = {
offset: { offset: {
x: 0, x: 0,
y: 0 y: 0
},
start: {
x: 0,
y: 0
} }
}, },
extend: function(obj1, obj2) { extend: function(obj1, obj2) {
@ -300,6 +296,14 @@ Kinetic.Node = function(config) {
} }
} }
} }
// overrides
if(this.centerOffset.x === undefined) {
this.centerOffset.x = 0;
}
if(this.centerOffset.y === undefined) {
this.centerOffset.y = 0;
}
}; };
/* /*
* Node methods * Node methods
@ -436,18 +440,7 @@ Kinetic.Node.prototype = {
* get absolute position relative to stage * get absolute position relative to stage
*/ */
getAbsolutePosition: function() { getAbsolutePosition: function() {
var x = this.x; return this.getAbsoluteTransform().getTranslation();
var y = this.y;
var parent = this.getParent();
while(parent.className !== 'Stage') {
x += parent.x;
y += parent.y;
parent = parent.parent;
}
return {
x: x,
y: y
};
}, },
/** /**
* move node by an amount * move node by an amount
@ -819,10 +812,8 @@ Kinetic.Node.prototype = {
var m = that.getTransform().getTranslation(); var m = that.getTransform().getTranslation();
var am = that.getAbsoluteTransform().getTranslation(); var am = that.getAbsoluteTransform().getTranslation();
go.drag.node = that; go.drag.node = that;
go.drag.offset.x = pos.x - that.x; go.drag.offset.x = pos.x - that.getAbsoluteTransform().getTranslation().x;
go.drag.offset.y = pos.y - that.y; go.drag.offset.y = pos.y - that.getAbsoluteTransform().getTranslation().y;
go.drag.start.x = m.x - am.x;
go.drag.start.y = m.y - am.y;
} }
}); });
}, },
@ -1581,21 +1572,43 @@ Kinetic.Stage.prototype = {
var pos = that.getUserPosition(); var pos = that.getUserPosition();
var dc = node.dragConstraint; var dc = node.dragConstraint;
var db = node.dragBounds; var db = node.dragBounds;
var m = node.getTransform().getTranslation();
var am = node.getAbsoluteTransform().getTranslation();
if(dc === 'none' || dc === 'horizontal') { // default
var newX = pos.x - go.drag.offset.x; var newNodePos = {
if((db.left === undefined || db.left < newX) && (db.right === undefined || db.right > newX)) { x: pos.x - go.drag.offset.x,
node.x = newX + m.x - (am.x + go.drag.start.x); y: pos.y - go.drag.offset.y
} };
// bounds overrides
if(db.left !== undefined && newNodePos.x < db.left) {
newNodePos.x = db.left;
} }
if(dc === 'none' || dc === 'vertical') { else if(db.right !== undefined && newNodePos.x > db.right) {
var newY = pos.y - go.drag.offset.y; newNodePos.x = db.right;
if((db.top === undefined || db.top < newY) && (db.bottom === undefined || db.bottom > newY)) {
node.y = newY + m.y - (am.y + go.drag.start.y);
}
} }
else if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.y = db.top;
}
else if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.y = db.bottom;
}
// constraint overrides
if(dc === 'horizontal') {
newNodePos.y = node.y;
}
else if(dc === 'vertical') {
newNodePos.x = node.x;
}
// magic
var it = node.getAbsoluteTransform();
it.invert();
it.translate(newNodePos.x, newNodePos.y);
node.x += it.getTranslation().x;
node.y += it.getTranslation().y;
go.drag.node.getLayer().draw(); go.drag.node.getLayer().draw();
if(!go.drag.moving) { if(!go.drag.moving) {
@ -2624,6 +2637,24 @@ Kinetic.Transform.prototype = {
this.m[4] = dx; this.m[4] = dx;
this.m[5] = dy; this.m[5] = dy;
}, },
/**
* Invert the matrix
*/
invert: function() {
var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);
var m0 = this.m[3] * d;
var m1 = -this.m[1] * d;
var m2 = -this.m[2] * d;
var m3 = this.m[0] * d;
var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);
var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);
this.m[0] = m0;
this.m[1] = m1;
this.m[2] = m2;
this.m[3] = m3;
this.m[4] = m4;
this.m[5] = m5;
},
/** /**
* return matrix * return matrix
*/ */

File diff suppressed because one or more lines are too long

View File

@ -24,10 +24,6 @@ Kinetic.GlobalObject = {
offset: { offset: {
x: 0, x: 0,
y: 0 y: 0
},
start: {
x: 0,
y: 0
} }
}, },
extend: function(obj1, obj2) { extend: function(obj1, obj2) {

View File

@ -49,6 +49,14 @@ Kinetic.Node = function(config) {
} }
} }
} }
// overrides
if(this.centerOffset.x === undefined) {
this.centerOffset.x = 0;
}
if(this.centerOffset.y === undefined) {
this.centerOffset.y = 0;
}
}; };
/* /*
* Node methods * Node methods
@ -185,18 +193,7 @@ Kinetic.Node.prototype = {
* get absolute position relative to stage * get absolute position relative to stage
*/ */
getAbsolutePosition: function() { getAbsolutePosition: function() {
var x = this.x; return this.getAbsoluteTransform().getTranslation();
var y = this.y;
var parent = this.getParent();
while(parent.className !== 'Stage') {
x += parent.x;
y += parent.y;
parent = parent.parent;
}
return {
x: x,
y: y
};
}, },
/** /**
* move node by an amount * move node by an amount
@ -568,10 +565,8 @@ Kinetic.Node.prototype = {
var m = that.getTransform().getTranslation(); var m = that.getTransform().getTranslation();
var am = that.getAbsoluteTransform().getTranslation(); var am = that.getAbsoluteTransform().getTranslation();
go.drag.node = that; go.drag.node = that;
go.drag.offset.x = pos.x - that.x; go.drag.offset.x = pos.x - that.getAbsoluteTransform().getTranslation().x;
go.drag.offset.y = pos.y - that.y; go.drag.offset.y = pos.y - that.getAbsoluteTransform().getTranslation().y;
go.drag.start.x = m.x - am.x;
go.drag.start.y = m.y - am.y;
} }
}); });
}, },

View File

@ -595,21 +595,43 @@ Kinetic.Stage.prototype = {
var pos = that.getUserPosition(); var pos = that.getUserPosition();
var dc = node.dragConstraint; var dc = node.dragConstraint;
var db = node.dragBounds; var db = node.dragBounds;
var m = node.getTransform().getTranslation();
var am = node.getAbsoluteTransform().getTranslation();
if(dc === 'none' || dc === 'horizontal') { // default
var newX = pos.x - go.drag.offset.x; var newNodePos = {
if((db.left === undefined || db.left < newX) && (db.right === undefined || db.right > newX)) { x: pos.x - go.drag.offset.x,
node.x = newX + m.x - (am.x + go.drag.start.x); y: pos.y - go.drag.offset.y
} };
// bounds overrides
if(db.left !== undefined && newNodePos.x < db.left) {
newNodePos.x = db.left;
} }
if(dc === 'none' || dc === 'vertical') { else if(db.right !== undefined && newNodePos.x > db.right) {
var newY = pos.y - go.drag.offset.y; newNodePos.x = db.right;
if((db.top === undefined || db.top < newY) && (db.bottom === undefined || db.bottom > newY)) {
node.y = newY + m.y - (am.y + go.drag.start.y);
}
} }
else if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.y = db.top;
}
else if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.y = db.bottom;
}
// constraint overrides
if(dc === 'horizontal') {
newNodePos.y = node.y;
}
else if(dc === 'vertical') {
newNodePos.x = node.x;
}
// magic
var it = node.getAbsoluteTransform();
it.invert();
it.translate(newNodePos.x, newNodePos.y);
node.x += it.getTranslation().x;
node.y += it.getTranslation().y;
go.drag.node.getLayer().draw(); go.drag.node.getLayer().draw();
if(!go.drag.moving) { if(!go.drag.moving) {

View File

@ -89,6 +89,24 @@ Kinetic.Transform.prototype = {
this.m[4] = dx; this.m[4] = dx;
this.m[5] = dy; this.m[5] = dy;
}, },
/**
* Invert the matrix
*/
invert: function() {
var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);
var m0 = this.m[3] * d;
var m1 = -this.m[1] * d;
var m2 = -this.m[2] * d;
var m3 = this.m[0] * d;
var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);
var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);
this.m[0] = m0;
this.m[1] = m1;
this.m[2] = m2;
this.m[3] = m3;
this.m[4] = m4;
this.m[5] = m5;
},
/** /**
* return matrix * return matrix
*/ */

View File

@ -988,7 +988,7 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({ var rect = new Kinetic.Rect({
x: 200, x: 200,
y: 80, y: 20,
width: 100, width: 100,
height: 50, height: 50,
fill: 'red', fill: 'red',
@ -1325,14 +1325,14 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var group = new Kinetic.Group({ var group = new Kinetic.Group({
scale: { scale: {
x: 1.5, x: 2,
y: 1.5 y: 2
} }
}); });
var circle = new Kinetic.Circle({ var circle = new Kinetic.Circle({
x: stage.width / 2, x: 40,
y: stage.height / 2, y: 40,
radius: 70, radius: 70,
fill: 'red', fill: 'red',
stroke: 'black', stroke: 'black',

View File

@ -1031,7 +1031,7 @@ Test.prototype.tests = {
layer.add(circle); layer.add(circle);
layer.draw(); layer.draw();
}, },
'SHAPES - move shape, group, and layer, and then get absolute position': function(containerId) { 'TRANSFORMS - move shape, group, and layer, and then get absolute position': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
container: containerId, container: containerId,
width: 578, width: 578,
@ -1069,6 +1069,44 @@ Test.prototype.tests = {
layer.draw(); layer.draw();
}, },
'TRANSFORMS - scale layer, rotate group, position shape, and then get absolute position': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer({
scale: {
x: 2,
y: 2
}
});
var group = new Kinetic.Group({
x: 100,
rotationDeg: 90
});
var rect = new Kinetic.Rect({
x: 50,
y: 10,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
group.add(rect);
layer.add(group);
stage.add(layer);
// test absolute positions
test(rect.getAbsolutePosition().x == 180, 'rect should be at x = 180');
test(rect.getAbsolutePosition().y == 100, 'rect should be at y = 100');
layer.draw();
},
'SHAPES - hide circle': function(containerId) { 'SHAPES - hide circle': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
container: containerId, container: containerId,