dragbound fixes

This commit is contained in:
Anton Lavrenov 2020-04-21 16:10:11 -05:00
parent 3173416b93
commit a7c9e0b5a5
5 changed files with 1468 additions and 79 deletions

View File

@ -5,7 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## Not released: ## Not released:
* new `Konva.Transformer` * **New `Konva.Transformer` implemenation!**
* Support of transforming multiple shapes at once: `tr.nodes([shape1, shape2])`.
* `tr.node()`, `tr.setNode()`, `tr.attachTo()` methods are deprecated. Use `tr.nodes(array)` instead
* Fixes for center scaling
* Fixes for better `padding` property support
* Transformer can be placed anywhere in the tree of a stage tree.
* Fix `imageSmoothEnabled` when stage is resized * Fix `imageSmoothEnabled` when stage is resized
* Memory usage optimizations when a node is cached * Memory usage optimizations when a node is cached

1419
konva.js

File diff suppressed because it is too large Load Diff

2
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -479,15 +479,15 @@ export class Transformer extends Group {
return this._getCache(NODES_RECT, this.__getNodeRect); return this._getCache(NODES_RECT, this.__getNodeRect);
} }
__getNodeShape(node, rot = this.rotation()) { __getNodeShape(node, rot = this.rotation(), relative?: Node) {
var rect = node.getClientRect({ var rect = node.getClientRect({
skipTransform: true, skipTransform: true,
skipShadow: true, skipShadow: true,
skipStroke: this.ignoreStroke() skipStroke: this.ignoreStroke()
}); });
var absScale = node.getAbsoluteScale(); var absScale = node.getAbsoluteScale(relative);
var absPos = node.getAbsolutePosition(); var absPos = node.getAbsolutePosition(relative);
var dx = rect.x * absScale.x - node.offsetX() * absScale.x; var dx = rect.x * absScale.x - node.offsetX() * absScale.x;
var dy = rect.y * absScale.y - node.offsetY() * absScale.y; var dy = rect.y * absScale.y - node.offsetY() * absScale.y;
@ -905,10 +905,6 @@ export class Transformer extends Group {
} }
_fitNodesInto(newAttrs, evt) { _fitNodesInto(newAttrs, evt) {
var oldAttrs = this._getNodeRect(); var oldAttrs = this._getNodeRect();
var boundBoxFunc = this.boundBoxFunc();
if (boundBoxFunc) {
newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs);
}
const minSize = 1; const minSize = 1;
@ -1011,6 +1007,22 @@ export class Transformer extends Group {
this.getLayer().batchDraw(); this.getLayer().batchDraw();
} }
_fitNodeInto(node: Node, newAttrs, evt) { _fitNodeInto(node: Node, newAttrs, evt) {
if (this.boundBoxFunc()) {
const oldAttrs = this.__getNodeShape(
node,
node.rotation(),
node.getParent()
);
const bounded = this.boundBoxFunc()(oldAttrs, newAttrs, node);
if (bounded) {
newAttrs = bounded;
} else {
Util.warn(
'boundBoxFunc returned falsy. You should return new bound rect from it!'
);
}
}
const parentRot = Konva.getAngle(node.getParent().getAbsoluteRotation()); const parentRot = Konva.getAngle(node.getParent().getAbsoluteRotation());
node.rotation(Util._getRotation(newAttrs.rotation - parentRot)); node.rotation(Util._getRotation(newAttrs.rotation - parentRot));
@ -1216,7 +1228,10 @@ export class Transformer extends Group {
keepRatio: GetSet<boolean, this>; keepRatio: GetSet<boolean, this>;
centeredScaling: GetSet<boolean, this>; centeredScaling: GetSet<boolean, this>;
ignoreStroke: GetSet<boolean, this>; ignoreStroke: GetSet<boolean, this>;
boundBoxFunc: GetSet<(oldBox: IRect, newBox: IRect) => IRect, this>; boundBoxFunc: GetSet<
(oldBox: IRect, newBox: IRect, node: Node) => IRect,
this
>;
shouldOverdrawWholeArea: GetSet<boolean, this>; shouldOverdrawWholeArea: GetSet<boolean, this>;
} }
@ -1588,7 +1603,7 @@ Factory.addGetterSetter(Transformer, 'node');
Factory.addGetterSetter(Transformer, 'nodes'); Factory.addGetterSetter(Transformer, 'nodes');
/** /**
* get/set bounding box function * get/set bounding box function. boundBondFunc operates is local coordinates of nodes parent
* @name Konva.Transformer#boundBoxFunc * @name Konva.Transformer#boundBoxFunc
* @method * @method
* @param {Function} func * @param {Function} func
@ -1598,7 +1613,9 @@ Factory.addGetterSetter(Transformer, 'nodes');
* var boundBoxFunc = transformer.boundBoxFunc(); * var boundBoxFunc = transformer.boundBoxFunc();
* *
* // set * // set
* transformer.boundBoxFunc(function(oldBox, newBox) { * transformer.boundBoxFunc(function(oldBox, newBox, node) {
* // width and height of the boxes are corresponding to total width and height of a node
* // so it includes scale of the node.
* if (newBox.width > 200) { * if (newBox.width > 200) {
* return oldBox; * return oldBox;
* } * }

View File

@ -931,7 +931,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
padding: 20 padding: 20
}); });
layer.add(tr); layer.add(tr);
@ -1061,7 +1061,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
rotationSnaps: [0, 90, 180, 270], rotationSnaps: [0, 90, 180, 270],
rotationSnapTolerance: 45 rotationSnapTolerance: 45
}); });
@ -1154,7 +1154,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
padding: 10 padding: 10
}); });
layer.add(tr); layer.add(tr);
@ -1222,7 +1222,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
padding: 10 padding: 10
}); });
layer.add(tr); layer.add(tr);
@ -1441,7 +1441,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
padding: 10 padding: 10
}); });
layer.add(tr); layer.add(tr);
@ -1511,7 +1511,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
padding: 10 padding: 10
}); });
layer.add(tr); layer.add(tr);
@ -2474,7 +2474,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
centeredScaling: true, centeredScaling: true,
keepRatio: false keepRatio: false
}); });
@ -2539,7 +2539,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
centeredScaling: true centeredScaling: true
}); });
layer.add(tr); layer.add(tr);
@ -2604,7 +2604,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
centeredScaling: true, centeredScaling: true,
keepRatio: true keepRatio: true
}); });
@ -2904,7 +2904,7 @@ suite('Transformer', function() {
layer.add(shape); layer.add(shape);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
node: [shape] nodes: [shape]
}); });
layer.add(tr); layer.add(tr);
@ -3339,7 +3339,7 @@ suite('Transformer', function() {
layer.add(rect); layer.add(rect);
var tr = new Konva.Transformer({ var tr = new Konva.Transformer({
nodes: [rect,] nodes: [rect],
keepRatio: false keepRatio: false
}); });
layer.add(tr); layer.add(tr);
@ -3819,4 +3819,64 @@ suite('Transformer', function() {
assert.equal(tr.height(), rect1.height() + rect2.height()); assert.equal(tr.height(), rect1.height() + rect2.height());
assert.equal(tr.rotation(), 0); assert.equal(tr.rotation(), 0);
}); });
test('boundBoxFox should work in local coordinates', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect1 = new Konva.Rect({
x: 0,
y: 0,
draggable: true,
width: 50,
height: 50,
fill: 'yellow'
});
layer.add(rect1);
var rect2 = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 50,
height: 50,
fill: 'red'
});
layer.add(rect2);
var tr = new Konva.Transformer({
nodes: [rect1, rect2],
boundBoxFunc: function(oldBox, newBox, node) {
if (node === rect1) {
assert.deepEqual(oldBox, {
x: 0,
y: 0,
width: 50,
height: 50,
rotation: 0
});
} else {
assert.deepEqual(oldBox, {
x: 50,
y: 50,
width: 50,
height: 50,
rotation: 0
});
}
return newBox;
}
});
layer.add(tr);
tr._fitNodesInto({
x: 0,
y: 0,
width: 100,
height: 100,
rotation: 0
});
});
}); });