konva/test/unit/shapes/Transformer-test.js
2019-09-17 12:57:01 -05:00

2432 lines
50 KiB
JavaScript

suite('Transformer', function() {
// ======================================================
test('init transformer on simple rectangle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), rect.x());
assert.equal(tr.y(), rect.y());
assert.equal(tr.width(), rect.width());
assert.equal(tr.height(), rect.height());
// manual check of correct position of node
var handler = tr.findOne('.bottom-right');
var pos = handler.getAbsolutePosition();
assert.equal(pos.x, rect.x() + rect.width());
assert.equal(pos.y, rect.y() + rect.height());
});
test('try it on a parent of parent', function() {
var callCount = 0;
var oldWarn = Konva.Util.warn;
Konva.Util.warn = function() {
callCount += 1;
};
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 50,
y: 50
});
layer.add(group);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
group.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
rect.width(120);
layer.draw();
assert.equal(callCount, 1);
Konva.Util.warn = oldWarn;
// assert.equal(tr.x(), rect.x() + group.x());
// assert.equal(tr.y(), rect.y() + group.y());
// assert.equal(tr.width(), rect.width());
// assert.equal(tr.height(), rect.height());
// // manual check of correct position of node
// var handler = tr.findOne('.bottom-right');
// var pos = handler.getAbsolutePosition();
// assert.equal(pos.x, rect.x() + rect.width());
// assert.equal(pos.y, rect.y() + rect.height());
});
test('try set/get node', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var circle = new Konva.Rect({
x: 10,
y: 60,
radius: 100,
fill: 'yellow'
});
layer.add(circle);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
assert.equal(tr.node(), rect);
tr.attachTo(circle);
assert.equal(tr.node(), circle);
});
test('try to fit simple rectangle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
tr._fitNodeInto({
x: 120,
y: 60,
width: 50,
height: 50,
rotation: 45
});
assert.equal(tr.x(), rect.x());
assert.equal(tr.y(), rect.y());
assert.equal(tr.width(), 50);
assert.equal(tr.height(), 50);
assert.equal(tr.rotation(), rect.rotation());
});
test('try to fit rectangle with ignoreStroke = false', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 20,
y: 20,
width: 100,
height: 100,
fill: 'green',
stroke: 'rgba(0,0,0,0.5)',
strokeWidth: 40,
name: 'myCircle',
draggable: true,
strokeScaleEnabled: false
});
layer.add(rect);
var tr = new Konva.Transformer({
ignoreStroke: true
});
layer.add(tr);
tr.attachTo(rect);
layer.draw();
tr._fitNodeInto({
x: 20,
y: 20,
width: 200,
height: 200
});
assert.equal(rect.x(), 20);
assert.equal(rect.y(), 20);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
assert.equal(rect.scaleX(), 2);
});
test('listen shape changes', 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();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
rect.setAttrs({
x: 50,
y: 50,
width: 100,
height: 100
});
layer.draw();
assert.equal(tr.x(), rect.x());
assert.equal(tr.y(), rect.y());
assert.equal(tr.width(), rect.width());
assert.equal(tr.height(), rect.height());
assert.equal(tr.findOne('.back').width(), rect.width());
});
test('add transformer for transformed rect', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 150,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
rotation: 90,
scaleY: 1.5
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), rect.x());
assert.equal(tr.y(), rect.y());
assert.equal(tr.width(), rect.width() * rect.scaleX());
assert.equal(tr.height(), rect.height() * rect.scaleY());
assert.equal(tr.rotation(), rect.rotation());
});
test('try to fit a transformed rect', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 150,
y: 60,
draggable: true,
width: 150,
height: 100,
fill: 'yellow',
rotation: 90,
scaleY: 1.5
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
tr._fitNodeInto({
x: 100,
y: 70,
width: 100,
height: 100
});
assert.equal(rect.x(), 100);
assert.equal(rect.y(), 70);
assert.equal(rect.width() * rect.scaleX(), 100);
assert.equal(rect.height() * rect.scaleY(), 100);
assert.equal(rect.rotation(), rect.rotation());
});
test('add transformer for transformed rect with offset', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 100,
draggable: true,
width: 100,
height: 100,
scaleX: 2,
scaleY: 2,
fill: 'yellow',
offsetX: 50,
offsetY: 50
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), rect.width() * rect.scaleX());
assert.equal(tr.height(), rect.height() * rect.scaleY());
assert.equal(tr.rotation(), rect.rotation());
});
test('fit rect with offset', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
offsetX: 50,
offsetY: 50
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
tr._fitNodeInto({
x: 0,
y: 0,
width: 200,
height: 100
});
layer.draw();
assert.equal(rect.x(), 100);
assert.equal(rect.y(), 50);
assert.equal(rect.width() * rect.scaleX(), 200);
assert.equal(rect.height() * rect.scaleY(), 100);
assert.equal(rect.rotation(), rect.rotation());
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), 200);
assert.equal(tr.height(), 100);
assert.equal(rect.rotation(), rect.rotation());
});
test('add transformer for circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var circle = new Konva.Circle({
x: 40,
y: 40,
draggable: true,
radius: 40,
fill: 'yellow'
});
layer.add(circle);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(circle);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), circle.width() * circle.scaleX());
assert.equal(tr.height(), circle.height() * circle.scaleY());
assert.equal(tr.rotation(), circle.rotation());
});
test('fit a circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var circle = new Konva.Circle({
x: 40,
y: 40,
draggable: true,
radius: 40,
fill: 'yellow'
});
layer.add(circle);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(circle);
tr._fitNodeInto({
x: 40,
y: 40,
width: 160,
height: 80
});
layer.draw();
assert.equal(circle.x(), 120);
assert.equal(circle.y(), 80);
assert.equal(circle.width() * circle.scaleX(), 160);
assert.equal(circle.height() * circle.scaleY(), 80);
assert.equal(tr.x(), 40);
assert.equal(tr.y(), 40);
assert.equal(tr.width(), 160);
assert.equal(tr.height(), 80);
});
test('fit a rotated circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var circle = new Konva.Circle({
x: 40,
y: 40,
draggable: true,
radius: 40,
fill: 'yellow'
});
layer.add(circle);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(circle);
tr._fitNodeInto({
x: 80,
y: 0,
width: 80,
height: 80,
rotation: 90
});
layer.draw();
assert.equal(circle.x(), 40);
assert.equal(circle.y(), 40);
assert.equal(circle.width() * circle.scaleX(), 80);
assert.equal(circle.height() * circle.scaleY(), 80);
assert.equal(circle.rotation(), 90);
assert.equal(tr.x(), 80);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), 80);
assert.equal(tr.height(), 80);
});
test('add transformer for transformed circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var circle = new Konva.Circle({
x: 100,
y: 100,
draggable: true,
radius: 40,
fill: 'yellow',
scaleX: 1.5
});
layer.add(circle);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(circle);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), 40);
assert.equal(tr.y(), 60);
assert.equal(tr.width(), 120);
assert.equal(tr.height(), 80);
assert.equal(tr.rotation(), 0);
});
test('add transformer for rotated circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var circle = new Konva.Circle({
x: 100,
y: 100,
draggable: true,
radius: 40,
fill: 'yellow',
scaleX: 1.5,
rotation: 90
});
layer.add(circle);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(circle);
layer.draw();
assert.equal(tr.x(), 140);
assert.equal(tr.y(), 40);
assert.equal(tr.width(), 120);
assert.equal(tr.height(), 80);
assert.equal(tr.rotation(), circle.rotation());
});
test('add transformer to group', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 50,
y: 50,
draggable: true
});
layer.add(group);
var shape1 = new Konva.Rect({
radius: 100,
fill: 'red',
x: 0,
y: 0,
width: 100,
height: 100
});
group.add(shape1);
var shape2 = new Konva.Rect({
radius: 100,
fill: 'yellow',
x: 50,
y: 50,
width: 100,
height: 100
});
group.add(shape2);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(group);
layer.draw();
assert.equal(tr.x(), group.x());
assert.equal(tr.y(), group.y());
assert.equal(tr.width(), 150);
assert.equal(tr.height(), 150);
assert.equal(tr.rotation(), 0);
});
test('rotated fit group', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 100,
y: 100,
draggable: true
});
layer.add(group);
var shape1 = new Konva.Rect({
fill: 'red',
x: -50,
y: -50,
width: 50,
height: 50
});
group.add(shape1);
var shape2 = new Konva.Rect({
fill: 'yellow',
x: 0,
y: 0,
width: 50,
height: 50
});
group.add(shape2);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(group);
tr._fitNodeInto({
x: 100,
y: 0,
width: 100,
height: 100,
rotation: 90
});
layer.draw();
var rect = group.getClientRect();
assert.equal(group.x(), 50);
assert.equal(group.y(), 50);
assert.equal(rect.width, 100);
assert.equal(rect.height, 100);
assert.equal(group.rotation(), 90);
assert.equal(tr.x(), 100);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), 100);
assert.equal(tr.height(), 100);
});
test('add transformer to another group', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 100,
y: 100,
draggable: true
});
layer.add(group);
var shape1 = new Konva.Rect({
fill: 'red',
x: -50,
y: -50,
width: 50,
height: 50
});
group.add(shape1);
var shape2 = new Konva.Rect({
fill: 'yellow',
x: 0,
y: 0,
width: 50,
height: 50
});
group.add(shape2);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(group);
layer.draw();
assert.equal(tr.x(), 50);
assert.equal(tr.y(), 50);
assert.equal(tr.width(), 100);
assert.equal(tr.height(), 100);
assert.equal(tr.rotation(), 0);
});
test('fit group', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 100,
y: 100,
draggable: true
});
layer.add(group);
var shape1 = new Konva.Rect({
fill: 'red',
x: -50,
y: -50,
width: 50,
height: 50
});
group.add(shape1);
var shape2 = new Konva.Rect({
fill: 'yellow',
x: 0,
y: 0,
width: 50,
height: 50
});
group.add(shape2);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(group);
tr._fitNodeInto({
x: 0,
y: 0,
width: 200,
height: 100
});
layer.draw();
var rect = group.getClientRect();
assert.equal(group.x(), 100);
assert.equal(group.y(), 50);
assert.equal(rect.width, 200);
assert.equal(rect.height, 100);
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), 200);
assert.equal(tr.height(), 100);
});
test('toJSON should not save attached node and children', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
var json = tr.toJSON();
var object = JSON.parse(json);
assert.equal(object.attrs.node, undefined);
assert.equal(object.children, undefined);
});
test('make sure we can work without inner node', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var tr = new Konva.Transformer();
layer.add(tr);
layer.draw();
});
test('reset attrs on node set', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
layer.draw();
assert.equal(tr.getWidth(), 0);
tr.attachTo(rect);
assert.equal(tr.getWidth(), 100);
});
test('can destroy without attached node', function() {
var tr = new Konva.Transformer();
tr.destroy();
});
test('can destroy with attached node while resize', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
stage.simulateMouseDown({
x: 100,
y: 60
});
assert.equal(tr.isTransforming(), true);
tr.destroy();
assert.equal(tr.isTransforming(), false);
assert.equal(tr.getNode(), undefined);
stage.simulateMouseUp({
x: 100,
y: 60
});
});
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,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
tr._fitNodeInto({
x: 0,
y: 0,
width: 120,
height: 120
});
layer.draw();
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
});
test.skip('test padding + keep ratio', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
const 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
});
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
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: 200,
clientY: 150 + top
});
stage.simulateMouseUp({
x: 200,
y: 150
});
layer.draw();
assert.equal(rect.x(), 50);
assert.equal(rect.y(), 50);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 50);
assert.equal(rect.scaleX(), 1);
assert.equal(rect.scaleY(), 1);
});
test('keep ratio should allow negative scaling', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 150,
y: 10,
draggable: true,
width: 50,
height: 50,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
var anchor = tr.findOne('.top-right');
var pos = anchor.getAbsolutePosition();
stage.simulateMouseDown({
x: pos.x,
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
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: box.left + pos.x - 100,
clientY: box.top + pos.y + 100
});
stage.simulateMouseUp({
x: pos.x - 100,
y: pos.y + 100
});
assert.equal(rect.scaleX(), -1);
assert.equal(rect.scaleY(), -1);
});
test('can add padding with rotation', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
padding: 10
});
layer.add(tr);
tr._fitNodeInto({
x: 120,
y: 0,
width: 120,
height: 120,
rotation: 90
});
layer.draw();
assert.equal(rect.x(), 110);
assert.equal(rect.y(), 10);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 90);
});
test('transformer should automatically track attr changes of a node', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
assert.equal(tr.x(), 100);
assert.equal(tr.y(), 60);
assert.equal(tr.width(), 100);
assert.equal(rect.height(), 100);
assert.equal(rect.rotation(), 0);
rect.x(0);
assert.equal(tr.x(), 0);
rect.y(0);
assert.equal(tr.y(), 0);
rect.width(50);
assert.equal(tr.width(), 50);
rect.height(50);
assert.equal(tr.height(), 50);
rect.scaleX(2);
assert.equal(tr.width(), 100);
rect.scaleY(2);
assert.equal(tr.height(), 100);
// manual check position
var back = tr.findOne('.back');
assert.equal(back.getAbsolutePosition().x, 0);
layer.batchDraw();
});
test('on detach should remove all listeners', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 100,
y: 60,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
tr.detach();
rect.width(200);
assert.equal(tr.width(), 0);
layer.draw();
var called = false;
// clear cache is called on each update
// make sure we don't call it
tr._clearCache = function() {
called = true;
};
rect.width(50);
assert.equal(called, false, 'don not call clear cache');
});
test('check transformer with drag&drop', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 0,
y: 0,
width: 100,
height: 100,
fill: 'green',
draggable: true
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
stage.simulateMouseDown({
x: 20,
y: 20
});
stage.simulateMouseMove({
x: 30,
y: 30
});
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 10);
assert.equal(tr.x(), 10);
assert.equal(tr.y(), 10);
stage.simulateMouseUp({
x: 30,
y: 30
});
});
test('check transformer with drag&drop and scaled shape', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 0,
y: 0,
width: 100,
height: 100,
fill: 'green',
draggable: true,
scaleX: 2
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
stage.simulateMouseDown({
x: 20,
y: 20
});
stage.simulateMouseMove({
x: 30,
y: 30
});
assert.equal(rect.x(), 10);
assert.equal(rect.y(), 10);
assert.equal(tr.x(), 10);
assert.equal(tr.y(), 10);
assert.equal(tr.width(), 200);
stage.simulateMouseUp({
x: 30,
y: 30
});
});
test('on negative scaleY should move rotater', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 160,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
scaleY: -1
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
var rotater = tr.findOne('.rotater');
var pos = rotater.getAbsolutePosition();
assert.equal(pos.x, 100);
assert.equal(pos.y, 210);
});
test('try rotated scaled rect', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 100,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
scaleY: -1
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
var rotater = tr.findOne('.rotater');
var pos = rotater.getAbsolutePosition();
stage.simulateMouseDown({
x: pos.x,
y: pos.y
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: rotater,
clientX: pos.x + 100,
clientY: pos.y - 100 + top
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: pos.x + 100,
clientY: pos.y - 50 + top
});
stage.simulateMouseUp({
x: 100,
y: 100
});
assert.equal(rect.rotation(), -90);
});
test('check correct cursor on scaled shape', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 100,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
scaleY: -1
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
stage.simulateMouseMove({
x: 50,
y: 1
});
assert.equal(stage.content.style.cursor, 'nwse-resize');
});
test('check correct cursor off on Transformer destroy', 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();
stage.simulateMouseMove({
x: 100,
y: 100
});
stage.simulateMouseDown({
x: 100,
y: 100
});
assert.equal(stage.content.style.cursor, 'nwse-resize');
var target = stage.getIntersection({
x: 100,
y: 100
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: target,
clientX: 120,
clientY: 100 + top
});
// here is duplicate, because transformer is listening window events
tr._handleMouseUp({
clientX: 120,
clientY: 100 + top
});
stage.simulateMouseUp({
x: 120,
y: 100
});
tr.destroy();
stage.simulateMouseMove({
x: 140,
y: 100
});
assert.equal(stage.content.style.cursor, '');
});
test('check correct cursor on scaled parent', function() {
var stage = addStage();
var layer = new Konva.Layer({
y: 100,
scaleY: -1
});
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
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();
stage.simulateMouseMove({
x: 50,
y: 1
});
assert.equal(stage.content.style.cursor, 'nwse-resize');
});
test('stopTransform method', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
stage.simulateMouseDown({
x: 50,
y: 50
});
var top = stage.content.getBoundingClientRect().top;
tr._handleMouseMove({
target: tr.findOne('.top-left'),
clientX: 60,
clientY: 60 + top
});
assert.equal(tr.isTransforming(), true);
assert.equal(rect.x(), 60);
var transformend = 0;
rect.on('transformend', function() {
transformend += 1;
});
tr.stopTransform();
assert.equal(transformend, 1);
assert.equal(tr.isTransforming(), false);
assert.equal(rect.x(), 60);
// here is duplicate, because transformer is listening window events
stage.simulateMouseUp({
x: 100,
y: 100
});
});
test('on force update should clear transform', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var group = new Konva.Group({
x: 50,
y: 50
});
layer.add(group);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(group);
layer.draw();
assert.equal(tr._cache.get('transform').m[4], 50);
var rect = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'yellow'
});
group.add(rect);
tr.forceUpdate();
layer.draw();
assert.equal(tr._cache.get('transform').m[4], 100);
// tr._fitNodeInto({
// x: 100,
// y: 70,
// width: 100,
// height: 100
// });
// assert.equal(rect.x(), 100);
// assert.equal(rect.y(), 70);
// assert.equal(rect.width() * rect.scaleX(), 100);
// assert.equal(rect.height() * rect.scaleY(), 100);
// assert.equal(rect.rotation(), rect.rotation());
});
test('test cache reset on attach', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 20,
y: 20,
draggable: true,
width: 150,
height: 100,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
// make draw to set all caches
layer.draw();
// then attach
tr.attachTo(rect);
layer.draw();
var shape = layer.getIntersection({
x: 20,
y: 20
});
assert.equal(shape.name(), 'top-left _anchor');
});
test('check rotator size on scaled transformer', function() {
var stage = addStage();
var layer = new Konva.Layer({
scaleX: 10,
scaleY: 10
});
stage.add(layer);
var rect = new Konva.Rect({
x: 5,
y: 16,
draggable: true,
width: 10,
height: 10,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
var rotater = tr.findOne('.rotater');
var pos = rotater.getAbsolutePosition();
// pos.x === (x * scaleX - (height))
assert.equal(pos.x, 100);
// pos.y === (y * scaleY - (height * scaleY / 2))
assert.equal(pos.y, 110);
});
var tests = [
{
name: 'top-left',
startPos: {
x: 0,
y: 0
},
endPos: {
x: 25,
y: 25
},
expectedWidth: 50,
expectedHeight: 50
},
{
name: 'top-center',
startPos: {
x: 50,
y: 0
},
endPos: {
x: 50,
y: 25
},
expectedWidth: 100,
expectedHeight: 50
},
{
name: 'top-right',
startPos: {
x: 100,
y: 0
},
endPos: {
x: 75,
y: 25
},
expectedWidth: 50,
expectedHeight: 50
},
{
name: 'middle-left',
startPos: {
x: 0,
y: 50
},
endPos: {
x: 25,
y: 50
},
expectedWidth: 50,
expectedHeight: 100
},
{
name: 'middle-right',
startPos: {
x: 100,
y: 50
},
endPos: {
x: 75,
y: 50
},
expectedWidth: 50,
expectedHeight: 100
},
{
name: 'bottom-left',
startPos: {
x: 0,
y: 100
},
endPos: {
x: 25,
y: 75
},
expectedWidth: 50,
expectedHeight: 50
},
{
name: 'bottom-center',
startPos: {
x: 50,
y: 100
},
endPos: {
x: 50,
y: 75
},
expectedWidth: 100,
expectedHeight: 50
},
{
name: 'bottom-right',
startPos: {
x: 100,
y: 100
},
endPos: {
x: 75,
y: 75
},
expectedWidth: 50,
expectedHeight: 50
}
];
test('if alt is pressed should transform around center', 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
});
layer.add(tr);
tests.forEach(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,
altKey: true
});
// 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();
stage.add(layer);
var rect = new Konva.Rect({
draggable: true,
fill: 'yellow'
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect,
centeredScaling: true
});
layer.add(tr);
tests.forEach(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('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,
scaleX: -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 < 1, true, ' width check');
assert.equal(rect.height() * rect.scaleY() - 50 < 1, true, ' height check');
});
test('transformer should ignore shadow', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
shadowBlur: 10
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
assert.equal(tr.x(), 50);
assert.equal(tr.y(), 50);
assert.equal(tr.width(), 100);
assert.equal(tr.height(), 100);
tr._fitNodeInto({
x: 50,
y: 50,
width: 100,
height: 100
});
assert.equal(rect.x(), 50);
assert.equal(rect.y(), 50);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
});
test.skip('transformer should skip scale on stroke if strokeScaleEnabled = false', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 10,
height: 10,
scaleX: 10,
scaleY: 10,
fill: 'yellow',
strokeWidth: 10,
stroke: 'red',
strokeScaleEnabled: false
});
layer.add(rect);
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
layer.draw();
assert.equal(tr.x(), 50);
assert.equal(tr.y(), 50);
assert.equal(tr.width(), 100);
assert.equal(tr.height(), 100);
tr._fitNodeInto({
x: 50,
y: 50,
width: 100,
height: 100
});
assert.equal(rect.x(), 50);
assert.equal(rect.y(), 50);
assert.equal(rect.width(), 100);
assert.equal(rect.height(), 100);
});
test('attrs change - arc', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Arc({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
innerRadius: 40,
outerRadius: 70,
angle: 60,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.outerRadius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
shape.innerRadius(200);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
layer.draw();
});
test('attrs change - line', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Arrow({
x: stage.getWidth() / 4,
y: stage.getHeight() / 4,
points: [0, 0, stage.width() / 2, stage.height() / 2],
pointerLength: 20,
pointerWidth: 20,
fill: 'black',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
layer.draw();
shape.points([10, 10, 100, 10]);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
layer.draw();
assert.deepEqual(shape.getClientRect(), rect);
shape.strokeWidth(10);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
layer.draw();
assert.deepEqual(shape.getClientRect(), rect);
});
test('attrs change - circle', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 40,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.radius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
});
test('attrs change - ellipse', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Ellipse({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: {
x: 100,
y: 50
},
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.radiusX(120);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
shape.radiusY(100);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
layer.draw();
});
test('attrs change - rect', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Rect({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
width: 100,
height: 100,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.width(120);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
shape.height(110);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
layer.draw();
});
test('attrs change - path', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Path({
x: 50,
y: 40,
data:
'M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z',
fill: 'green'
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.data('M200,100h100v50z');
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
});
test('attrs change - regular polygon', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.RegularPolygon({
x: 100,
y: 150,
sides: 6,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.radius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
});
test('attrs change - ring', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Ring({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
innerRadius: 40,
outerRadius: 70,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.outerRadius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
shape.innerRadius(200);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
layer.draw();
});
test('attrs change - star', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Star({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
numPoints: 6,
innerRadius: 40,
outerRadius: 70,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.outerRadius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
shape.innerRadius(200);
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
layer.draw();
});
test('attrs change - wedge', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
angle: 60,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.radius(100);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect);
});
test('attrs change - text', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.Text({
x: stage.getWidth() / 2,
y: 15,
text: 'Simple Text',
fontSize: 60,
fontFamily: 'Calibri',
fill: 'green'
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.text('Simple');
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change text');
shape.fontSize(30);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change font size');
shape.padding(10);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change padding');
shape.lineHeight(2);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change line height');
shape.width(30);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect), 'change width';
shape.height(30);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change height');
});
test('attrs change - text path', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var shape = new Konva.TextPath({
x: 0,
y: 50,
fill: '#333',
fontSize: 16,
fontFamily: 'Arial',
text:
"All the world's a stage, and all the men and women merely players.",
data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50'
});
layer.add(shape);
var tr = new Konva.Transformer({
node: shape
});
layer.add(tr);
shape.text('Simple');
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change text');
shape.fontSize(30);
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect, 'change font size');
shape.data('M10,10 C0,0 10,150 100,100 S300,150 400,50');
layer.draw();
var rect = Object.assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect), 'change data';
});
test('make sure transformer events are not cloned', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
const rect1 = new Konva.Rect({
x: stage.width() / 5,
y: stage.height() / 5,
width: 50,
height: 50,
fill: 'green',
draggable: true
});
layer.add(rect1);
const tr1 = new Konva.Transformer({
node: rect1
});
layer.add(tr1);
const rect2 = rect1.clone({
fill: 'red',
x: stage.width() / 3,
y: stage.height() / 3
});
layer.add(rect2);
tr1.destroy();
let tr2 = new Konva.Transformer({
node: rect2
});
layer.add(tr2);
// should not throw error
rect2.width(100);
stage.draw();
});
});