From 51371a8140653fb08d73f744195cdb8243d966c1 Mon Sep 17 00:00:00 2001 From: Anton Lavrenov Date: Tue, 29 Jun 2021 11:44:22 +0700 Subject: [PATCH] New property `useSingleNodeRotation` for `Konva.Transformer` --- CHANGELOG.md | 4 ++++ src/Shape.ts | 4 ++-- src/shapes/Transformer.ts | 42 +++++++++++++++++++++++++++++++---- test/unit/Transformer-test.ts | 33 ++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8843f6f9..e3b2ecb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 8.1.0 + +- New property `useSingleNodeRotation` for `Konva.Transformer`. + ## 8.0.4 - Fix fill pattern updates on `fillPatternX` and `fillPatternY` changes. diff --git a/src/Shape.ts b/src/Shape.ts index ce2bdee4..bc1e4eb0 100644 --- a/src/Shape.ts +++ b/src/Shape.ts @@ -199,12 +199,12 @@ export class Shape< getContext() { Util.warn( - 'shape.getContext() method is deprecated. Please don not use it.' + 'shape.getContext() method is deprecated. Please do not use it.' ); return this.getLayer().getContext(); } getCanvas() { - Util.warn('shape.getCanvas() method is deprecated. Please don not use it.'); + Util.warn('shape.getCanvas() method is deprecated. Please do not use it.'); return this.getLayer().getCanvas(); } diff --git a/src/shapes/Transformer.ts b/src/shapes/Transformer.ts index 9c9e0ada..8ff5d1bd 100644 --- a/src/shapes/Transformer.ts +++ b/src/shapes/Transformer.ts @@ -37,6 +37,8 @@ export interface TransformerConfig extends ContainerConfig { node?: Rect; ignoreStroke?: boolean; boundBoxFunc?: (oldBox: Box, newBox: Box) => Box; + useSingleNodeRotation?: boolean; + shouldOverdrawWholeArea?: boolean; } var EVENTS_NAME = 'tr-konva'; @@ -221,7 +223,8 @@ function getSnap(snaps: Array, newRotationRad: number, tol: number) { * @param {Boolean} [config.flipEnabled] Can we flip/mirror shape on transform?. True by default * @param {Function} [config.boundBoxFunc] Bounding box function * @param {Function} [config.ignoreStroke] Should we ignore stroke size? Default is false - * + * @param {Boolean} [config.useSingleNodeRotation] When just one node attached, should we use its rotation for transformer? + * @param {Boolean} [config.shouldOverdrawWholeArea] Should we fill whole transformer area with fake transparent shape to enable dragging from empty spaces? * @example * var transformer = new Konva.Transformer({ * nodes: [rectangle], @@ -284,7 +287,7 @@ export class Transformer extends Group { this.detach(); } this._nodes = nodes; - if (nodes.length === 1) { + if (nodes.length === 1 && this.useSingleNodeRotation()) { this.rotation(nodes[0].getAbsoluteRotation()); } else { this.rotation(0); @@ -295,8 +298,7 @@ export class Transformer extends Group { .join(' '); const onChange = () => { - // - if (this.nodes().length === 1) { + if (this.nodes().length === 1 && this.useSingleNodeRotation()) { this.rotation(this.nodes()[0].getAbsoluteRotation()); } @@ -1225,6 +1227,7 @@ export class Transformer extends Group { ignoreStroke: GetSet; boundBoxFunc: GetSet<(oldBox: Box, newBox: Box) => Box, this>; shouldOverdrawWholeArea: GetSet; + useSingleNodeRotation: GetSet; } function validateAnchors(val) { @@ -1629,8 +1632,39 @@ Factory.addGetterSetter(Transformer, 'nodes'); */ Factory.addGetterSetter(Transformer, 'boundBoxFunc'); +/** + * using this setting you can drag transformer group by dragging empty space between attached nodes + * shouldOverdrawWholeArea = true may temporary disable all events on attached nodes + * @name Konva.Transformer#shouldOverdrawWholeArea + * @method + * @param {Boolean} shouldOverdrawWholeArea + * @returns {Boolean} + * @example + * // get + * var shouldOverdrawWholeArea = transformer.shouldOverdrawWholeArea(); + * + * // set + * transformer.shouldOverdrawWholeArea(true); + */ Factory.addGetterSetter(Transformer, 'shouldOverdrawWholeArea', false); +/** + * If you have just one attached node to Transformer it will set its initial rotation to the rotation of that node. + * In some cases you may need to set a different rotation. + * @name Konva.Transformer#useSingleNodeRotation + * @method + * @param {Boolean} useSingleNodeRotation + * @returns {Boolean} + * @example + * // set flag to false + * transformer.useSingleNodeRotation(false); + * // attach a shape + * transformer.nodes([shape]); + * transformer.rotation(45); + * transformer.update(); + */ + Factory.addGetterSetter(Transformer, 'useSingleNodeRotation', true); + Factory.backCompat(Transformer, { lineEnabled: 'borderEnabled', rotateHandlerOffset: 'rotateAnchorOffset', diff --git a/test/unit/Transformer-test.ts b/test/unit/Transformer-test.ts index a6ff3a9b..0c204a8b 100644 --- a/test/unit/Transformer-test.ts +++ b/test/unit/Transformer-test.ts @@ -36,7 +36,7 @@ function simulateMouseUp(tr: Transformer, pos = { x: 0, y: 0 }) { su(tr.getStage(), pos || { x: 1, y: 1 }); } -describe('Transformer', function () { +describe.only('Transformer', function () { // ====================================================== it('init transformer on simple rectangle', function () { var stage = addStage(); @@ -4620,4 +4620,35 @@ describe('Transformer', function () { assert.equal(textNode.getClientRect().width, 100); }); + + // ====================================================== + it('init transformer on simple rectangle', function () { + var stage = addStage(); + stage.rotation(45); + + 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', + rotation: 45 + }); + layer.add(rect); + + var tr = new Konva.Transformer({ + useSingleNodeRotation: false, + nodes: [rect], + }); + layer.add(tr); + + layer.draw(); + assert.equal(tr.getClassName(), 'Transformer'); + + assert.equal(tr.rotation(), 0); + }); });