mirror of
https://github.com/konvajs/konva.git
synced 2025-10-15 12:34:52 +08:00
Fix Konva.Transformer
behavior on mirrored nodes. close #732
This commit is contained in:
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Not released:
|
||||
|
||||
* Fix `Konva.Transformer` behavior on mirrored nodes
|
||||
* Fix `stage.getPointerPosition()` logic.
|
||||
|
||||
## 4.0.8 - 2019-09-05
|
||||
|
101
konva.js
101
konva.js
@@ -13546,7 +13546,7 @@
|
||||
this.add(back);
|
||||
};
|
||||
Transformer.prototype._handleMouseDown = function (e) {
|
||||
this.movingResizer = e.target.name().split(' ')[0];
|
||||
this._movingAnchorName = e.target.name().split(' ')[0];
|
||||
// var node = this.getNode();
|
||||
var attrs = this._getNodeRect();
|
||||
var width = attrs.width;
|
||||
@@ -13564,8 +13564,8 @@
|
||||
};
|
||||
Transformer.prototype._handleMouseMove = function (e) {
|
||||
var x, y, newHypotenuse;
|
||||
var resizerNode = this.findOne('.' + this.movingResizer);
|
||||
var stage = resizerNode.getStage();
|
||||
var anchorNode = this.findOne('.' + this._movingAnchorName);
|
||||
var stage = anchorNode.getStage();
|
||||
var box = stage.getContent().getBoundingClientRect();
|
||||
var zeroPoint = {
|
||||
x: box.left,
|
||||
@@ -13579,84 +13579,96 @@
|
||||
x: pointerPos.left - zeroPoint.x,
|
||||
y: pointerPos.top - zeroPoint.y
|
||||
};
|
||||
resizerNode.setAbsolutePosition(newAbsPos);
|
||||
anchorNode.setAbsolutePosition(newAbsPos);
|
||||
var keepProportion = this.keepRatio() || e.shiftKey;
|
||||
// console.log(keepProportion);
|
||||
if (this.movingResizer === 'top-left') {
|
||||
if (this._movingAnchorName === 'top-left') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-right').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y() - resizerNode.y(), 2));
|
||||
var reverse = this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-right').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y() - anchorNode.y(), 2));
|
||||
var reverseX = this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY = this.findOne('.top-left').y() > this.findOne('.bottom-right').y()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
this.findOne('.top-left').x(this.findOne('.bottom-right').x() - x);
|
||||
this.findOne('.top-left').y(this.findOne('.bottom-right').y() - y);
|
||||
}
|
||||
}
|
||||
else if (this.movingResizer === 'top-center') {
|
||||
this.findOne('.top-left').y(resizerNode.y());
|
||||
else if (this._movingAnchorName === 'top-center') {
|
||||
this.findOne('.top-left').y(anchorNode.y());
|
||||
}
|
||||
else if (this.movingResizer === 'top-right') {
|
||||
else if (this._movingAnchorName === 'top-right') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-left').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-left').y() - resizerNode.y(), 2));
|
||||
var reverse = this.findOne('.top-right').x() < this.findOne('.top-left').x()
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-left').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-left').y() - anchorNode.y(), 2));
|
||||
var reverseX = this.findOne('.top-right').x() < this.findOne('.top-left').x()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY = this.findOne('.top-right').y() > this.findOne('.bottom-left').y()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
this.findOne('.top-right').x(x);
|
||||
this.findOne('.top-right').y(this.findOne('.bottom-left').y() - y);
|
||||
}
|
||||
var pos = resizerNode.position();
|
||||
var pos = anchorNode.position();
|
||||
this.findOne('.top-left').y(pos.y);
|
||||
this.findOne('.bottom-right').x(pos.x);
|
||||
}
|
||||
else if (this.movingResizer === 'middle-left') {
|
||||
this.findOne('.top-left').x(resizerNode.x());
|
||||
else if (this._movingAnchorName === 'middle-left') {
|
||||
this.findOne('.top-left').x(anchorNode.x());
|
||||
}
|
||||
else if (this.movingResizer === 'middle-right') {
|
||||
this.findOne('.bottom-right').x(resizerNode.x());
|
||||
else if (this._movingAnchorName === 'middle-right') {
|
||||
this.findOne('.bottom-right').x(anchorNode.x());
|
||||
}
|
||||
else if (this.movingResizer === 'bottom-left') {
|
||||
else if (this._movingAnchorName === 'bottom-left') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.top-right').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.top-right').y() - resizerNode.y(), 2));
|
||||
var reverse = this.findOne('.top-right').x() < this.findOne('.bottom-left').x()
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.top-right').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.top-right').y() - anchorNode.y(), 2));
|
||||
var reverseX = this.findOne('.top-right').x() < this.findOne('.bottom-left').x()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY = this.findOne('.bottom-right').y() < this.findOne('.top-left').y()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
this.findOne('.bottom-left').x(this.findOne('.top-right').x() - x);
|
||||
this.findOne('.bottom-left').y(y);
|
||||
}
|
||||
pos = resizerNode.position();
|
||||
pos = anchorNode.position();
|
||||
this.findOne('.top-left').x(pos.x);
|
||||
this.findOne('.bottom-right').y(pos.y);
|
||||
}
|
||||
else if (this.movingResizer === 'bottom-center') {
|
||||
this.findOne('.bottom-right').y(resizerNode.y());
|
||||
else if (this._movingAnchorName === 'bottom-center') {
|
||||
this.findOne('.bottom-right').y(anchorNode.y());
|
||||
}
|
||||
else if (this.movingResizer === 'bottom-right') {
|
||||
else if (this._movingAnchorName === 'bottom-right') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(Math.pow(this.findOne('.bottom-right').x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y(), 2));
|
||||
var reverse = this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
var reverseX = this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY = this.findOne('.top-left').y() > this.findOne('.bottom-right').y()
|
||||
? -1
|
||||
: 1;
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
this.findOne('.bottom-right').x(x);
|
||||
this.findOne('.bottom-right').y(y);
|
||||
}
|
||||
}
|
||||
else if (this.movingResizer === 'rotater') {
|
||||
else if (this._movingAnchorName === 'rotater') {
|
||||
var padding = this.padding();
|
||||
var attrs = this._getNodeRect();
|
||||
x = resizerNode.x() - attrs.width / 2;
|
||||
y = -resizerNode.y() + attrs.height / 2;
|
||||
x = anchorNode.x() - attrs.width / 2;
|
||||
y = -anchorNode.y() + attrs.height / 2;
|
||||
var dAlpha = Math.atan2(-y, x) + Math.PI / 2;
|
||||
if (attrs.height < 0) {
|
||||
dAlpha -= Math.PI;
|
||||
@@ -13696,9 +13708,10 @@
|
||||
}, e);
|
||||
}
|
||||
else {
|
||||
console.error(new Error('Wrong position argument of selection resizer: ' + this.movingResizer));
|
||||
console.error(new Error('Wrong position argument of selection resizer: ' +
|
||||
this._movingAnchorName));
|
||||
}
|
||||
if (this.movingResizer === 'rotater') {
|
||||
if (this._movingAnchorName === 'rotater') {
|
||||
return;
|
||||
}
|
||||
var absPos = this.findOne('.top-left').getAbsolutePosition(this.getParent());
|
||||
@@ -13906,9 +13919,9 @@
|
||||
Transformer.prototype.stopTransform = function () {
|
||||
if (this._transforming) {
|
||||
this._removeEvents();
|
||||
var resizerNode = this.findOne('.' + this.movingResizer);
|
||||
if (resizerNode) {
|
||||
resizerNode.stopDrag();
|
||||
var anchorNode = this.findOne('.' + this._movingAnchorName);
|
||||
if (anchorNode) {
|
||||
anchorNode.stopDrag();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -180,7 +180,7 @@ var MAX_SAFE_INTEGER = 100000000;
|
||||
|
||||
export class Transformer extends Group {
|
||||
_node: Node;
|
||||
movingResizer: string;
|
||||
_movingAnchorName: string;
|
||||
_transforming = false;
|
||||
sin: number;
|
||||
cos: number;
|
||||
@@ -405,7 +405,7 @@ export class Transformer extends Group {
|
||||
this.add(back);
|
||||
}
|
||||
_handleMouseDown(e) {
|
||||
this.movingResizer = e.target.name().split(' ')[0];
|
||||
this._movingAnchorName = e.target.name().split(' ')[0];
|
||||
|
||||
// var node = this.getNode();
|
||||
var attrs = this._getNodeRect();
|
||||
@@ -427,8 +427,8 @@ export class Transformer extends Group {
|
||||
}
|
||||
_handleMouseMove(e) {
|
||||
var x, y, newHypotenuse;
|
||||
var resizerNode = this.findOne('.' + this.movingResizer);
|
||||
var stage = resizerNode.getStage();
|
||||
var anchorNode = this.findOne('.' + this._movingAnchorName);
|
||||
var stage = anchorNode.getStage();
|
||||
|
||||
var box = stage.getContent().getBoundingClientRect();
|
||||
var zeroPoint = {
|
||||
@@ -444,106 +444,126 @@ export class Transformer extends Group {
|
||||
y: pointerPos.top - zeroPoint.y
|
||||
};
|
||||
|
||||
resizerNode.setAbsolutePosition(newAbsPos);
|
||||
anchorNode.setAbsolutePosition(newAbsPos);
|
||||
|
||||
var keepProportion = this.keepRatio() || e.shiftKey;
|
||||
|
||||
// console.log(keepProportion);
|
||||
|
||||
if (this.movingResizer === 'top-left') {
|
||||
if (this._movingAnchorName === 'top-left') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(
|
||||
Math.pow(this.findOne('.bottom-right').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y() - resizerNode.y(), 2)
|
||||
Math.pow(this.findOne('.bottom-right').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y() - anchorNode.y(), 2)
|
||||
);
|
||||
|
||||
var reverse =
|
||||
var reverseX =
|
||||
this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY =
|
||||
this.findOne('.top-left').y() > this.findOne('.bottom-right').y()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
|
||||
this.findOne('.top-left').x(this.findOne('.bottom-right').x() - x);
|
||||
this.findOne('.top-left').y(this.findOne('.bottom-right').y() - y);
|
||||
}
|
||||
} else if (this.movingResizer === 'top-center') {
|
||||
this.findOne('.top-left').y(resizerNode.y());
|
||||
} else if (this.movingResizer === 'top-right') {
|
||||
} else if (this._movingAnchorName === 'top-center') {
|
||||
this.findOne('.top-left').y(anchorNode.y());
|
||||
} else if (this._movingAnchorName === 'top-right') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(
|
||||
Math.pow(this.findOne('.bottom-left').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-left').y() - resizerNode.y(), 2)
|
||||
Math.pow(this.findOne('.bottom-left').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-left').y() - anchorNode.y(), 2)
|
||||
);
|
||||
|
||||
var reverse =
|
||||
var reverseX =
|
||||
this.findOne('.top-right').x() < this.findOne('.top-left').x()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY =
|
||||
this.findOne('.top-right').y() > this.findOne('.bottom-left').y()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
|
||||
this.findOne('.top-right').x(x);
|
||||
this.findOne('.top-right').y(this.findOne('.bottom-left').y() - y);
|
||||
}
|
||||
var pos = resizerNode.position();
|
||||
var pos = anchorNode.position();
|
||||
|
||||
this.findOne('.top-left').y(pos.y);
|
||||
this.findOne('.bottom-right').x(pos.x);
|
||||
} else if (this.movingResizer === 'middle-left') {
|
||||
this.findOne('.top-left').x(resizerNode.x());
|
||||
} else if (this.movingResizer === 'middle-right') {
|
||||
this.findOne('.bottom-right').x(resizerNode.x());
|
||||
} else if (this.movingResizer === 'bottom-left') {
|
||||
} else if (this._movingAnchorName === 'middle-left') {
|
||||
this.findOne('.top-left').x(anchorNode.x());
|
||||
} else if (this._movingAnchorName === 'middle-right') {
|
||||
this.findOne('.bottom-right').x(anchorNode.x());
|
||||
} else if (this._movingAnchorName === 'bottom-left') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(
|
||||
Math.pow(this.findOne('.top-right').x() - resizerNode.x(), 2) +
|
||||
Math.pow(this.findOne('.top-right').y() - resizerNode.y(), 2)
|
||||
Math.pow(this.findOne('.top-right').x() - anchorNode.x(), 2) +
|
||||
Math.pow(this.findOne('.top-right').y() - anchorNode.y(), 2)
|
||||
);
|
||||
|
||||
var reverse =
|
||||
var reverseX =
|
||||
this.findOne('.top-right').x() < this.findOne('.bottom-left').x()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY =
|
||||
this.findOne('.bottom-right').y() < this.findOne('.top-left').y()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
|
||||
this.findOne('.bottom-left').x(this.findOne('.top-right').x() - x);
|
||||
this.findOne('.bottom-left').y(y);
|
||||
}
|
||||
|
||||
pos = resizerNode.position();
|
||||
pos = anchorNode.position();
|
||||
|
||||
this.findOne('.top-left').x(pos.x);
|
||||
this.findOne('.bottom-right').y(pos.y);
|
||||
} else if (this.movingResizer === 'bottom-center') {
|
||||
this.findOne('.bottom-right').y(resizerNode.y());
|
||||
} else if (this.movingResizer === 'bottom-right') {
|
||||
} else if (this._movingAnchorName === 'bottom-center') {
|
||||
this.findOne('.bottom-right').y(anchorNode.y());
|
||||
} else if (this._movingAnchorName === 'bottom-right') {
|
||||
if (keepProportion) {
|
||||
newHypotenuse = Math.sqrt(
|
||||
Math.pow(this.findOne('.bottom-right').x(), 2) +
|
||||
Math.pow(this.findOne('.bottom-right').y(), 2)
|
||||
);
|
||||
|
||||
var reverse =
|
||||
var reverseX =
|
||||
this.findOne('.top-left').x() > this.findOne('.bottom-right').x()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverse;
|
||||
y = newHypotenuse * this.sin * reverse;
|
||||
var reverseY =
|
||||
this.findOne('.top-left').y() > this.findOne('.bottom-right').y()
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
x = newHypotenuse * this.cos * reverseX;
|
||||
y = newHypotenuse * this.sin * reverseY;
|
||||
|
||||
this.findOne('.bottom-right').x(x);
|
||||
this.findOne('.bottom-right').y(y);
|
||||
}
|
||||
} else if (this.movingResizer === 'rotater') {
|
||||
} else if (this._movingAnchorName === 'rotater') {
|
||||
var padding = this.padding();
|
||||
var attrs = this._getNodeRect();
|
||||
x = resizerNode.x() - attrs.width / 2;
|
||||
y = -resizerNode.y() + attrs.height / 2;
|
||||
x = anchorNode.x() - attrs.width / 2;
|
||||
y = -anchorNode.y() + attrs.height / 2;
|
||||
|
||||
var dAlpha = Math.atan2(-y, x) + Math.PI / 2;
|
||||
|
||||
@@ -599,12 +619,13 @@ export class Transformer extends Group {
|
||||
} else {
|
||||
console.error(
|
||||
new Error(
|
||||
'Wrong position argument of selection resizer: ' + this.movingResizer
|
||||
'Wrong position argument of selection resizer: ' +
|
||||
this._movingAnchorName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (this.movingResizer === 'rotater') {
|
||||
if (this._movingAnchorName === 'rotater') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -839,9 +860,9 @@ export class Transformer extends Group {
|
||||
stopTransform() {
|
||||
if (this._transforming) {
|
||||
this._removeEvents();
|
||||
var resizerNode = this.findOne('.' + this.movingResizer);
|
||||
if (resizerNode) {
|
||||
resizerNode.stopDrag();
|
||||
var anchorNode = this.findOne('.' + this._movingAnchorName);
|
||||
if (anchorNode) {
|
||||
anchorNode.stopDrag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -624,7 +624,7 @@ suite('TouchEvents', function() {
|
||||
assert.equal(dbltap, 0, 'no dbltap triggered');
|
||||
});
|
||||
|
||||
test.only('tap should give pointer position', function() {
|
||||
test('tap should give pointer position', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
@@ -1814,6 +1814,64 @@ suite('Transformer', function() {
|
||||
});
|
||||
});
|
||||
|
||||
test('transform scaled (in one direction) node', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
var rect = new Konva.Rect({
|
||||
draggable: true,
|
||||
fill: 'yellow',
|
||||
x: 150,
|
||||
y: 50,
|
||||
width: 100,
|
||||
height: 100,
|
||||
scaleY: -1
|
||||
});
|
||||
layer.add(rect);
|
||||
|
||||
var tr = new Konva.Transformer({
|
||||
node: rect
|
||||
});
|
||||
layer.add(tr);
|
||||
|
||||
layer.draw();
|
||||
|
||||
stage.simulateMouseDown({
|
||||
x: 150,
|
||||
y: 150
|
||||
});
|
||||
|
||||
var target = stage.getIntersection({
|
||||
x: 150,
|
||||
y: 150
|
||||
});
|
||||
var top = Math.round(stage.content.getBoundingClientRect().top);
|
||||
tr._handleMouseMove({
|
||||
target: target,
|
||||
clientX: 100,
|
||||
clientY: 100 + top
|
||||
});
|
||||
|
||||
// here is duplicate, because transformer is listening window events
|
||||
tr._handleMouseUp({
|
||||
clientX: 100,
|
||||
clientY: 100 + top
|
||||
});
|
||||
stage.simulateMouseUp({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
layer.draw();
|
||||
|
||||
assert.equal(rect.width() * rect.scaleX() + 50 < 0.1, true, ' width check');
|
||||
assert.equal(
|
||||
rect.height() * rect.scaleY() - 50 < 0.1,
|
||||
true,
|
||||
' height check'
|
||||
);
|
||||
});
|
||||
|
||||
test('transformer should ignore shadow', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
Reference in New Issue
Block a user