Avoid crash when node inside transformer was destroyed. close #1957

This commit is contained in:
Anton Lavrevov 2025-08-18 23:47:44 +09:00
parent c621b39f99
commit 4cad96ff73
2 changed files with 53 additions and 2 deletions

View File

@ -788,9 +788,11 @@ export class Transformer extends Group {
Math.pow(comparePoint.y - anchorNode.y(), 2)
);
const reverseX = this.findOne('.top-left')!.x() > comparePoint.x ? -1 : 1;
const reverseX =
this.findOne('.top-left')!.x() > comparePoint.x ? -1 : 1;
const reverseY = this.findOne('.top-left')!.y() > comparePoint.y ? -1 : 1;
const reverseY =
this.findOne('.top-left')!.y() > comparePoint.y ? -1 : 1;
x = newHypotenuse * this.cos * reverseX;
y = newHypotenuse * this.sin * reverseY;
@ -1107,6 +1109,16 @@ export class Transformer extends Group {
const delta = newTr.multiply(oldTr.invert());
this._nodes.forEach((node) => {
// check to close this issue: https://github.com/konvajs/konva/issues/1957
// a node can be destroyed during the transformation
// probably a developer must remove it from transformer
if (!node.getStage()) {
// do we need a helping message?
// Util.error(
// 'Node is not attached to the stage. This is not allowed. Please attach the node to the stage before transforming. If node was destroyed, make sure to remove it from transformer.'
// );
return;
}
// for each node we have the same [delta transform]
// the equations is
// [delta transform] * [parent transform] * [old local transform] = [parent transform] * [new local transform]

View File

@ -5141,4 +5141,43 @@ describe('Transformer', function () {
'Event listeners should be cleaned up properly'
);
});
it.only('should handle transformation when node is not on stage (case for node destroy)', function () {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
// Create a rect but don't add it to stage yet
var rect = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'yellow',
});
var tr = new Konva.Transformer({
nodes: [rect],
});
layer.add(tr);
// Should not throw error when drawing with node not on stage
layer.draw();
// Transformer should have zero size when node is not on stage
// Try to move an anchor to trigger transformation - should throw error
simulateMouseDown(tr, {
x: 50,
y: 50,
});
simulateMouseMove(tr, {
x: 60,
y: 60,
});
simulateMouseUp(tr, {
x: 60,
y: 60,
});
});
});