mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 00:14:29 +08:00
reworked transformation matrix operations with drag and drop
This commit is contained in:
parent
1fa41e6692
commit
f312c0cf9d
91
dist/kinetic-core.js
vendored
91
dist/kinetic-core.js
vendored
@ -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;
|
||||||
}
|
}
|
||||||
|
else if(db.right !== undefined && newNodePos.x > db.right) {
|
||||||
|
newNodePos.x = db.right;
|
||||||
}
|
}
|
||||||
if(dc === 'none' || dc === 'vertical') {
|
else if(db.top !== undefined && newNodePos.y < db.top) {
|
||||||
var newY = pos.y - go.drag.offset.y;
|
newNodePos.y = db.top;
|
||||||
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.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
|
||||||
*/
|
*/
|
||||||
|
2
dist/kinetic-core.min.js
vendored
2
dist/kinetic-core.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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) {
|
||||||
|
27
src/Node.js
27
src/Node.js
@ -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;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
42
src/Stage.js
42
src/Stage.js
@ -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;
|
||||||
}
|
}
|
||||||
|
else if(db.right !== undefined && newNodePos.x > db.right) {
|
||||||
|
newNodePos.x = db.right;
|
||||||
}
|
}
|
||||||
if(dc === 'none' || dc === 'vertical') {
|
else if(db.top !== undefined && newNodePos.y < db.top) {
|
||||||
var newY = pos.y - go.drag.offset.y;
|
newNodePos.y = db.top;
|
||||||
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.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) {
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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',
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user