some transformer fixes

This commit is contained in:
Anton Lavrenov 2020-04-06 21:51:03 -05:00
parent 185c599257
commit 55c812425d
4 changed files with 932 additions and 1540 deletions

1543
konva.js

File diff suppressed because it is too large Load Diff

View File

@ -218,7 +218,7 @@ export abstract class BaseLayer extends Container<Group | Shape> {
this.getContext()._context.imageSmoothingEnabled = this.imageSmoothingEnabled();
}
/**
* get/set width of layer.getter return width of stage. setter doing nothing.
* get/set width of layer. getter return width of stage. setter doing nothing.
* if you want change width use `stage.width(value);`
* @name Konva.BaseLayer#width
* @method
@ -302,10 +302,8 @@ BaseLayer.prototype.nodeType = 'BaseLayer';
* // get imageSmoothingEnabled flag
* var imageSmoothingEnabled = layer.imageSmoothingEnabled();
*
* // disable clear before draw
* layer.imageSmoothingEnabled(false);
*
* // enable clear before draw
* layer.imageSmoothingEnabled(true);
*/
Factory.addGetterSetter(BaseLayer, 'imageSmoothingEnabled', true);

View File

@ -145,7 +145,15 @@ var ANCHORS_NAMES = [
var MAX_SAFE_INTEGER = 100000000;
function getCenter(shape) {
type SHAPE = {
x: number;
y: number;
width: number;
height: number;
rotation: number;
};
function getCenter(shape: SHAPE) {
return {
x:
shape.x +
@ -158,7 +166,7 @@ function getCenter(shape) {
};
}
function rotateAroundPoint(shape, angleRad, point) {
function rotateAroundPoint(shape: SHAPE, angleRad: number, point: Point) {
const x =
point.x +
(shape.x - point.x) * Math.cos(angleRad) -
@ -175,12 +183,12 @@ function rotateAroundPoint(shape, angleRad, point) {
};
}
function rotateAroundCenter(shape, deltaRad) {
function rotateAroundCenter(shape: SHAPE, deltaRad: number) {
const center = getCenter(shape);
return rotateAroundPoint(shape, deltaRad, center);
}
function getShapeRect(shape) {
function getShapeRect(shape: SHAPE) {
const angleRad = shape.rotation;
const x1 = shape.x;
const y1 = shape.y;
@ -209,7 +217,7 @@ function getShapeRect(shape) {
};
}
function getShapesRect(shapes) {
function getShapesRect(shapes: Array<SHAPE>) {
// if (shapes.length === 1) {
// const shape = shapes[0];
@ -242,25 +250,16 @@ function getShapesRect(shapes) {
};
}
function isOverlap(rect1, rect2) {
const offset = 0;
if (rect1.x - offset > rect2.x + rect2.width) {
return false;
}
if (rect1.x + rect1.width + offset < rect2.x) {
return false;
}
if (rect1.y - offset > rect2.y + rect2.height) {
return false;
}
if (rect1.y + rect1.height + offset < rect2.y) {
return false;
}
return true;
}
function transformShape(shape, oldSelection, newSelection, keepOffset = 1) {
const offset = rotateAroundPoint(shape, -oldSelection.rotation, oldSelection);
function transformShape(
shape: SHAPE,
oldSelection: SHAPE,
newSelection: SHAPE,
keepOffset = 1
) {
const offset = rotateAroundPoint(shape, -oldSelection.rotation, {
x: oldSelection.x,
y: oldSelection.y
});
const offsetX = offset.x - oldSelection.x;
const offsetY = offset.y - oldSelection.y;
@ -279,14 +278,19 @@ function transformShape(shape, oldSelection, newSelection, keepOffset = 1) {
offsetX * scaleX * Math.sin(angle) +
offsetY * scaleY * Math.cos(angle),
width: shape.width * scaleX,
height: shape.height * scaleY
height: shape.height * scaleY,
rotation: shape.rotation
};
}
function transformAndRotateShape(shape, oldSelection, newSelection) {
function transformAndRotateShape(
shape: SHAPE,
oldSelection: SHAPE,
newSelection: SHAPE
) {
const updated = transformShape(shape, oldSelection, newSelection);
return rotateAroundPoint(
{ ...updated, rotation: shape.rotation },
updated,
newSelection.rotation - oldSelection.rotation,
newSelection
);
@ -580,22 +584,22 @@ export class Transformer extends Group {
strokeWidth: 1,
name: name + ' _anchor',
dragDistance: 0,
draggable: true,
draggable: false,
hitStrokeWidth: TOUCH_DEVICE ? 10 : 'auto'
});
var self = this;
anchor.on('mousedown touchstart', function(e) {
self._handleMouseDown(e);
});
anchor.on('dragstart', function(e) {
e.cancelBubble = true;
});
anchor.on('dragmove', function(e) {
e.cancelBubble = true;
});
anchor.on('dragend', function(e) {
e.cancelBubble = true;
});
// anchor.on('dragstart', function(e) {
// e.cancelBubble = true;
// });
// anchor.on('dragmove', function(e) {
// e.cancelBubble = true;
// });
// anchor.on('dragend', function(e) {
// e.cancelBubble = true;
// });
// add hover styling
anchor.on('mouseenter', () => {
@ -697,13 +701,47 @@ export class Transformer extends Group {
x: pp.x - this._anchorDragOffset.x,
y: pp.y - this._anchorDragOffset.y
};
const oldAbs = anchorNode.getAbsolutePosition();
anchorNode.setAbsolutePosition(newNodePos);
const newAbs = anchorNode.getAbsolutePosition();
if (oldAbs.x === newAbs.x && oldAbs.y === newAbs.y) {
return;
}
var centeredScaling = this.centeredScaling() || e.altKey;
// if (centeredScaling && this._movingAnchorName.indexOf('left') >= 0) {
// var topLeft = this.findOne('.top-left');
// var bottomRight = this.findOne('.bottom-right');
// var topOffsetX = topLeft.x() + padding;
// var topOffsetY = topLeft.y() + padding;
// var bottomOffsetX = this.getWidth() - bottomRight.x() + padding;
// var bottomOffsetY = this.getHeight() - bottomRight.y() + padding;
// bottomRight.move({
// x: -anchorNode.x(),
// y: -anchorNode.y()
// });
// topLeft.move({
// x: bottomOffsetX,
// y: bottomOffsetY
// });
// }
var keepProportion = this.keepRatio() || e.shiftKey;
var padding = 0;
if (this._movingAnchorName === 'top-left') {
// if (centeredScaling) {
// this.findOne('.bottom-right').move({
// x: -anchorNode.x(),
// y: -anchorNode.y()
// });
// }
if (keepProportion) {
newHypotenuse = Math.sqrt(
Math.pow(
@ -737,8 +775,32 @@ export class Transformer extends Group {
);
}
} else if (this._movingAnchorName === 'top-center') {
// if (centeredScaling) {
// this.findOne('.bottom-right').move({
// x: 0,
// y: -anchorNode.y()
// });
// }
this.findOne('.top-left').y(anchorNode.y());
} else if (this._movingAnchorName === 'top-right') {
if (centeredScaling) {
// this.findOne('.bottom-left').move({
// x: -(anchorNode.x() - this.width()),
// y: -anchorNode.y()
// });
// this.findOne('.top-left').move({
// x: -(anchorNode.x() - this.width()),
// y: anchorNode.y()
// });
// this.findOne('.bottom-right').move({
// x: -(anchorNode.x() - this.width()),
// y: anchorNode.y()
// });
}
// var center = getCenter({
// x
// })
if (keepProportion) {
newHypotenuse = Math.sqrt(
Math.pow(
@ -770,14 +832,31 @@ export class Transformer extends Group {
);
}
var pos = anchorNode.position();
this.findOne('.top-left').y(pos.y);
this.findOne('.bottom-right').x(pos.x);
} else if (this._movingAnchorName === 'middle-left') {
// if (centeredScaling) {
// this.findOne('.bottom-right').move({
// x: -anchorNode.x(),
// y: 0
// });
// }
this.findOne('.top-left').x(anchorNode.x());
} else if (this._movingAnchorName === 'middle-right') {
// if (centeredScaling) {
// this.findOne('.top-left').move({
// x: -(anchorNode.x() - this.width()),
// y: 0
// });
// }
this.findOne('.bottom-right').x(anchorNode.x());
} else if (this._movingAnchorName === 'bottom-left') {
// if (centeredScaling) {
// this.findOne('.bottom-right').move({
// x: -anchorNode.x(),
// y: -(anchorNode.y() - this.height())
// });
// }
if (keepProportion) {
newHypotenuse = Math.sqrt(
Math.pow(
@ -814,8 +893,21 @@ export class Transformer extends Group {
this.findOne('.top-left').x(pos.x);
this.findOne('.bottom-right').y(pos.y);
} else if (this._movingAnchorName === 'bottom-center') {
// if (centeredScaling) {
// this.findOne('.top-left').move({
// x: 0,
// y: -(anchorNode.y() - this.height())
// });
// }
this.findOne('.bottom-right').y(anchorNode.y());
} else if (this._movingAnchorName === 'bottom-right') {
// if (centeredScaling) {
// this.findOne('.top-left').move({
// x: -(anchorNode.x() - this.width()),
// y: -(anchorNode.y() - this.height())
// });
// }
if (keepProportion) {
newHypotenuse = Math.sqrt(
Math.pow(this.findOne('.bottom-right').x() - padding, 2) +
@ -910,9 +1002,7 @@ export class Transformer extends Group {
});
}
var absPos = this.findOne('.top-left').getAbsolutePosition(
this.getParent()
);
var absPos = this.findOne('.top-left').getAbsolutePosition();
x = absPos.x;
y = absPos.y;
@ -924,8 +1014,8 @@ export class Transformer extends Group {
this._fitNodesInto(
{
x: x + this.offsetX(),
y: y + this.offsetY(),
x: x,
y: y,
width: width,
height: height,
rotation: Konva.getAngle(this.rotation())
@ -956,43 +1046,88 @@ export class Transformer extends Group {
}
}
_fitNodesInto(newAttrs, evt) {
// console.log(newAttrs, oldAttrs);
// waring! in this attrs padding is included
var oldAttrs = this._getNodeRect();
var boundBoxFunc = this.boundBoxFunc();
if (boundBoxFunc) {
newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs);
}
console.log(newAttrs.width, newAttrs.height);
if (newAttrs.width < 1 && newAttrs.width > - this.padding() * 2) {
const minSize = 1;
if (Util._inRange(newAttrs.width, -this.padding() * 2 - minSize, minSize)) {
this.update();
return;
}
if (Math.abs(newAttrs.height) < 1) {
if (
Util._inRange(newAttrs.height, -this.padding() * 2 - minSize, minSize)
) {
this.update();
return;
}
// if (newAttrs.width < 0) {
// debugger;
// }
const an = this._movingAnchorName;
const allowNegativeScale = true;
var t = new Transform();
t.rotate(Konva.getAngle(this.rotation()));
if (an && newAttrs.width < 0 && an.indexOf('left') >= 0) {
const offset = t.point({
x: -this.padding() * 2,
y: 0
});
newAttrs.x += offset.x;
newAttrs.y += offset.y;
newAttrs.width += this.padding() * 2;
this._movingAnchorName = an.replace('left', 'right');
this._anchorDragOffset.x += this.padding() * 2;
this.update();
return;
this._anchorDragOffset.x -= offset.x;
this._anchorDragOffset.y -= offset.y;
if (!allowNegativeScale) {
this.update();
return;
}
} else if (an && newAttrs.width < 0 && an.indexOf('right') >= 0) {
const offset = t.point({
x: this.padding() * 2,
y: 0
});
this._movingAnchorName = an.replace('right', 'left');
this._anchorDragOffset.x -= this.padding() * 2;
this.update();
return;
} else if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) {
this._anchorDragOffset.x -= offset.x;
this._anchorDragOffset.y -= offset.y;
newAttrs.width += this.padding() * 2;
if (!allowNegativeScale) {
this.update();
return;
}
}
if (an && newAttrs.height < 0 && an.indexOf('top') >= 0) {
const offset = t.point({
x: 0,
y: -this.padding() * 2
});
newAttrs.x += offset.x;
newAttrs.y += offset.y;
this._movingAnchorName = an.replace('top', 'bottom');
this._anchorDragOffset.y += this.padding() * 2;
this.update();
return;
this._anchorDragOffset.x -= offset.x;
this._anchorDragOffset.y -= offset.y;
newAttrs.height += this.padding() * 2;
if (!allowNegativeScale) {
this.update();
return;
}
} else if (an && newAttrs.height < 0 && an.indexOf('bottom') >= 0) {
const offset = t.point({
x: 0,
y: this.padding() * 2
});
this._movingAnchorName = an.replace('bottom', 'top');
this._anchorDragOffset.y -= this.padding() * 2;
this.update();
return;
this._anchorDragOffset.x -= offset.x;
this._anchorDragOffset.y -= offset.y;
newAttrs.height += this.padding() * 2;
if (!allowNegativeScale) {
this.update();
return;
}
}
this._nodes.forEach(node => {
var oldRect = this.__getNodeShape(node, 0);

View File

@ -1,4 +1,26 @@
suite.only('Transformer', function() {
function isClose(a, b) {
return Math.abs(a - b) < 0.000001;
}
Konva.Transformer.prototype.simulateMouseDown = function(pos) {
this.getStage().simulateMouseDown(pos);
};
Konva.Transformer.prototype.simulateMouseMove = function(pos) {
var top = this.getStage().content.getBoundingClientRect().top;
this._handleMouseMove({
clientX: pos.x,
clientY: pos.y + top
});
this.getStage().simulateMouseMove(pos);
};
Konva.Transformer.prototype.simulateMouseUp = function(pos) {
this._handleMouseUp(pos);
this.getStage().simulateMouseUp(pos || { x: 1, y: 1 });
};
// ======================================================
test('init transformer on simple rectangle', function() {
var stage = addStage();
@ -196,7 +218,7 @@ suite.only('Transformer', function() {
assert.equal(tr.rotation(), rect.rotation());
});
test.skip('try to fit simple rectangle into negative scale', function() {
test('try to fit simple rectangle into negative scale', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
@ -227,8 +249,6 @@ suite.only('Transformer', function() {
tr._fitNodesInto(box);
assert.deepEqual(box, tr.__getNodeRect());
assert.equal(rect.x(), 100);
assert.equal(rect.y(), 0);
assert.equal(rect.width(), 100);
@ -939,14 +959,14 @@ suite.only('Transformer', function() {
});
});
test.only('can add padding', function() {
test('can add padding', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
x: 30,
y: 30,
draggable: true,
width: 100,
height: 100,
@ -956,77 +976,36 @@ suite.only('Transformer', function() {
var tr = new Konva.Transformer({
node: rect,
padding: 50
});
layer.add(tr);
tr._fitNodesInto({
x: 20,
y: 20,
width: 100,
height: 100,
rotation: 0
});
layer.draw();
assert.equal(rect.x(), 20);
assert.equal(rect.y(), 20);
assert.equal(rect.width(), 120);
assert.equal(rect.height(), 120);
});
test.skip('test padding + keep ratio', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
width: 180,
height: 50,
fill: 'red',
draggable: true
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 40,
keepRatio: true
padding: 20
});
layer.add(tr);
layer.draw();
stage.simulateMouseDown({
x: 250,
y: 150
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: tr.findOne('.bottom-right'),
clientX: 200,
clientY: 150 + top
x: 10,
y: 80
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
clientX: 60,
clientY: 80 + top
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: 200,
clientY: 150 + top
clientY: 150
});
stage.simulateMouseUp({
x: 200,
y: 150
});
layer.draw();
assert.equal(rect.x(), 50);
assert.equal(rect.y(), 50);
assert.equal(rect.x(), 80);
assert.equal(rect.y(), 30);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 50);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleX(), 0.5);
assert.equal(rect.height(), 100);
assert.equal(rect.scaleY(), 1);
});
@ -1051,6 +1030,11 @@ suite.only('Transformer', function() {
layer.add(tr);
layer.draw();
// rect.on('transform', () => {
// console.log(tr.getActiveAnchor(), tr._anchorDragOffset);
// });
// throw 1;
var anchor = tr.findOne('.top-right');
var pos = anchor.getAbsolutePosition();
@ -1059,9 +1043,7 @@ suite.only('Transformer', function() {
y: pos.y
});
var box = stage.content.getBoundingClientRect();
// debugger;
tr._handleMouseMove({
target: anchor,
clientX: box.left + pos.x - 100,
clientY: box.top + pos.y + 100
});
@ -1080,14 +1062,36 @@ suite.only('Transformer', function() {
assert.equal(rect.scaleY(), -1);
});
test('can add padding with rotation', function() {
test.skip('visual test', function(done) {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var src = 'assets/darth-vader.jpg';
Konva.Image.fromURL(src, function(image) {
image.setAttrs({
draggable: true,
scaleX: 0.5,
scaleY: 0.5
});
layer.add(image);
var tr = new Konva.Transformer({
node: image,
keepRatio: false
});
layer.add(tr);
layer.draw();
done();
});
});
test('switch scaling with padding - x', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
x: 10,
y: 10,
draggable: true,
width: 100,
height: 100,
@ -1101,21 +1105,411 @@ suite.only('Transformer', function() {
});
layer.add(tr);
tr._fitNodesInto({
x: 120,
y: 0,
width: 120,
height: 120,
rotation: Konva.getAngle(90)
layer.draw();
tr.simulateMouseDown({
x: 0,
y: 60
});
tr.simulateMouseMove({
x: 125,
y: 60
});
assert.equal(rect.x(), 115);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
tr.simulateMouseMove({
x: 125,
y: 60
});
assert.equal(rect.x(), 115);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.scaleY(), -1);
// switch again
tr.simulateMouseMove({
x: 90,
y: 60
});
assert.equal(rect.x(), 100);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleY(), -1);
assert.equal(rect.scaleX() + 0.1 < 0.0001, true);
assert.equal(rect.height(), 100);
tr.simulateMouseUp();
});
test('switch scaling with padding - y', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 10,
y: 10,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
layer.draw();
tr.simulateMouseDown({
x: 60,
y: 0
});
tr.simulateMouseMove({
x: 60,
y: 125
});
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 115);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleY(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
tr.simulateMouseMove({
x: 60,
y: 125
});
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 115);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleY(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
// switch again
tr.simulateMouseMove({
x: 60,
y: 90
});
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 100);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleY(), 0.1);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
tr.simulateMouseUp();
});
test('switch horizontal scaling with (top-left anchor)', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 0,
y: 0,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
tr.simulateMouseDown({
x: 0,
y: 0
});
tr.simulateMouseMove({
x: 150,
y: 50
});
layer.draw();
assert.equal(rect.x(), 150);
assert.equal(rect.y(), 50);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), -0.5);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
tr.simulateMouseMove({
x: 98,
y: 2.859375
});
tr.simulateMouseMove({
x: 98,
y: 2.859375
});
tr.simulateMouseMove({
x: 98,
y: 2.859375
});
tr.simulateMouseMove({
x: 100,
y: 2.859375
});
layer.draw();
tr.simulateMouseMove({
x: 101,
y: 2.859375
});
layer.draw();
tr.simulateMouseMove({
x: 101,
y: 2.859375
});
layer.draw();
tr.simulateMouseMove({
x: 101,
y: 2.859375
});
layer.draw();
tr.simulateMouseMove({
x: 102,
y: 2.859375
});
layer.draw();
// switch again
tr.simulateMouseMove({
x: 0,
y: 0
});
assert.equal(isClose(rect.x(), 0), true);
assert.equal(Math.round(rect.y()), 0);
assert.equal(rect.width(), 100);
assert.equal(Math.round(rect.scaleY()), -1);
assert.equal(Math.round(rect.scaleX()), -1);
assert.equal(rect.height(), 100);
tr.simulateMouseUp();
});
// TODO: doesn't work!!!
test.skip('switch vertical scaling with (top-left anchor)', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 0,
y: 0,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
tr.simulateMouseDown({
x: 0,
y: 0
});
tr.simulateMouseMove({
x: 0,
y: 200
});
layer.draw();
assert.equal(rect.x(), 0);
assert.equal(rect.y(), 200);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
tr.simulateMouseMove({
x: 0,
y: 0
});
layer.draw();
tr.simulateMouseUp();
assert.equal(rect.x(), 0);
assert.equal(rect.y(), 100);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
assert.equal(rect.scaleY(), -1);
});
test('switch scaling with padding for rotated - x', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 110,
y: 10,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
rotation: 90
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
layer.draw();
tr.simulateMouseDown({
x: 60,
y: 0
});
tr.simulateMouseMove({
x: 60,
y: 125
});
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 115);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 90);
tr.simulateMouseMove({
x: 60,
y: 125
});
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 115);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.scaleY(), -1);
// switch again
tr.simulateMouseMove({
x: 60,
y: 90
});
assert.equal(rect.x(), 110);
assert.equal(rect.y() - 120 < 0.001, true);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX() + 0.1 < 0.0001, true);
assert.equal(rect.scaleY(), -1);
assert.equal(rect.height(), 100);
tr.simulateMouseUp();
});
test('switch scaling with padding for rotated - y', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 110,
y: 10,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
rotation: 90
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
layer.draw();
tr.simulateMouseDown({
x: 0,
y: 60
});
tr.simulateMouseMove({
x: 125,
y: 60
});
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleY(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 90);
tr.simulateMouseMove({
x: 125,
y: 60
});
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleY(), -0.05);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 90);
// switch again
tr.simulateMouseMove({
x: 90,
y: 60
});
assert.equal(rect.x(), 110);
assert.equal(rect.y() - 120 < 0.001, true);
assert.equal(rect.width(), 100);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleY(), 0.1);
assert.equal(rect.height(), 100);
tr.simulateMouseUp();
});
test('transformer should automatically track attr changes of a node', function() {
@ -1368,7 +1762,6 @@ suite.only('Transformer', function() {
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: rotater,
clientX: pos.x + 100,
clientY: pos.y - 100 + top
});
@ -1453,7 +1846,6 @@ suite.only('Transformer', function() {
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: target,
clientX: 120,
clientY: 100 + top
});
@ -1581,7 +1973,6 @@ suite.only('Transformer', function() {
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: tr.findOne('.top-left'),
clientX: 60,
clientY: 60 + top
});
@ -1670,7 +2061,6 @@ suite.only('Transformer', function() {
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: tr.findOne('.top-left'),
clientX: 60,
clientY: 60 + top
});
@ -1984,6 +2374,71 @@ suite.only('Transformer', function() {
});
});
test('centered scaling - no keep ratio', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
draggable: true,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
centeredScaling: true,
keepRatio: false
});
layer.add(tr);
tests.forEach(function(test) {
rect.setAttrs({
x: 0,
y: 0,
width: 100,
height: 100,
scaleX: 1,
scaleY: 1
});
tr.update();
layer.draw();
stage.simulateMouseDown(test.startPos);
var target = stage.getIntersection(test.startPos);
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: target,
clientX: test.endPos.x,
clientY: test.endPos.y + top
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: test.endPos.x,
clientY: test.endPos.y + top
});
stage.simulateMouseUp({
x: test.endPos.x,
y: test.endPos.y
});
layer.draw();
assert.equal(
rect.width() * rect.scaleX(),
test.expectedWidth,
test.name + ' width check'
);
assert.equal(
rect.height() * rect.scaleY(),
test.expectedHeight,
test.name + ' height check'
);
});
});
test('centered scaling', function() {
var stage = addStage();
var layer = new Konva.Layer();
@ -2048,7 +2503,7 @@ suite.only('Transformer', function() {
});
});
test.skip('centered scaling on flip', function() {
test.only('centered scaling on flip + keep ratio', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
@ -2062,14 +2517,14 @@ suite.only('Transformer', function() {
var tr = new Konva.Transformer({
node: rect,
centeredScaling: true,
keepRatio: false
keepRatio: true
});
layer.add(tr);
rect.setAttrs({
x: 0,
y: 0,
width: 100,
width: 200,
height: 100,
scaleX: 1,
scaleY: 1
@ -2078,39 +2533,36 @@ suite.only('Transformer', function() {
layer.draw();
// stage.simulateMouseDown({x: 0, y: 0});
tr.simulateMouseDown({
x: 0,
y: 0
});
tr.simulateMouseMove({
x: 200,
y: 0
});
assert.equal(isClose(rect.x(), 200), true);
assert.equal(isClose(rect.y(), 0), true);
assert.equal(rect.width(), 200);
assert.equal(Math.round(rect.scaleY()), 1);
assert.equal(Math.round(rect.scaleX()), -1);
assert.equal(rect.height(), 100);
var target = stage.getIntersection({ x: 0, y: 0 });
var top = stage.content.getBoundingClientRect().top;
throw 11;
debugger;
tr._handleMouseMove({
target: target,
clientX: 100,
clientY: 0 + top
tr.simulateMouseMove({
x: 200,
y: 0
});
console.log(rect.width() * rect.scaleX());
tr._handleMouseMove({
target: target,
clientX: 100,
clientY: 0 + top
});
console.log(rect.width() * rect.scaleX());
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: 100,
clientY: 0 + top
});
stage.simulateMouseUp({
x: 100,
tr.simulateMouseUp({
x: 0,
y: 0
});
layer.draw();
assert.equal(rect.width() * rect.scaleX(), -100);
assert.equal(rect.height() * rect.scaleY(), -100);
throw 1;
assert.equal(isClose(rect.x(), 200), true);
assert.equal(isClose(rect.y(), 0), true);
assert.equal(rect.width(), 200);
assert.equal(Math.round(rect.scaleY()), -1);
assert.equal(Math.round(rect.scaleX()), 1);
assert.equal(rect.height(), 100);
});
test('transform scaled (in one direction) node', function() {
@ -2149,7 +2601,6 @@ suite.only('Transformer', function() {
});
var top = Math.round(stage.content.getBoundingClientRect().top);
tr._handleMouseMove({
target: target,
clientX: 100,
clientY: 100 + top
});
@ -2800,7 +3251,6 @@ suite.only('Transformer', function() {
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: target,
clientX: 100,
clientY: 50 + top
});