new centeredScaling for Konva.Transformer

This commit is contained in:
Anton Lavrenov 2018-09-19 14:59:01 +03:00
parent f7ed3f7d52
commit 4ac38ddc1f
6 changed files with 218 additions and 112 deletions

View File

@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
* Centered resize with ALT key for `Konva.Transformer`
* New `centeredScaling` for `Konva.Transformer`
## [2.3.0][2018-08-30]

9
konva.d.ts vendored
View File

@ -1174,6 +1174,7 @@ declare namespace Konva {
anchorStrokeWidth?: number;
anchorSize?: number;
keepRatio?: boolean;
centeredScaling?: boolean;
enabledAnchors?: Array<string>;
node?: Rect;
boundBoxFunc?: (oldBox: SizeConfig, newBox: SizeConfig) => SizeConfig;
@ -1187,8 +1188,12 @@ declare namespace Konva {
detach(): void;
forceUpdate(): void;
resizeEnabled(): boolean;
resizeEnabled(enabled: boolean): this;
keepRatio(): boolean;
keepRatio(enabled: boolean): this;
keepRatio(): boolean;
keepRatio(enabled: boolean): this;
centeredScaling(): boolean;
centeredScaling(enabled: boolean): this;
rotateEnabled(): boolean;
rotateEnabled(enabled: boolean): this;
rotationSnaps(): Array<number>;

View File

@ -19552,6 +19552,7 @@
* @param {Number} [config.anchorStrokeWidth] Anchor stroke size
* @param {Number} [config.anchorSize] Default is 10
* @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true
* @param {Boolean} [config.centeredScaling] Should we resize relative to node's center? Default is false
* @param {Array} [config.enabledAnchors] Array of names of enabled handles
* @param {Function} [config.boundBoxFunc] Bounding box function
* @example
@ -20002,7 +20003,8 @@
this.getParent()
);
if (e.altKey) {
var centeredScaling = this.getCenteredScaling() || e.altKey;
if (centeredScaling) {
var topLeft = this.findOne('.top-left');
var bottomRight = this.findOne('.bottom-right');
var topOffsetX = topLeft.x();
@ -20515,6 +20517,22 @@
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
/**
* get/set should we resize relative to node's center?
* @name centeredScaling
* @method
* @memberof Konva.Transformer.prototype
* @param {Boolean} centeredScaling
* @returns {Boolean}
* @example
* // get
* var centeredScaling = transformer.centeredScaling();
*
* // set
* transformer.centeredScaling(true);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'centeredScaling', false);
/**
* get/set padding
* @name padding

2
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -125,6 +125,7 @@
* @param {Number} [config.anchorStrokeWidth] Anchor stroke size
* @param {Number} [config.anchorSize] Default is 10
* @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true
* @param {Boolean} [config.centeredScaling] Should we resize relative to node's center? Default is false
* @param {Array} [config.enabledAnchors] Array of names of enabled handles
* @param {Function} [config.boundBoxFunc] Bounding box function
* @example
@ -575,7 +576,8 @@
this.getParent()
);
if (e.altKey) {
var centeredScaling = this.getCenteredScaling() || e.altKey;
if (centeredScaling) {
var topLeft = this.findOne('.top-left');
var bottomRight = this.findOne('.bottom-right');
var topOffsetX = topLeft.x();
@ -1088,6 +1090,22 @@
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
/**
* get/set should we resize relative to node's center?
* @name centeredScaling
* @method
* @memberof Konva.Transformer.prototype
* @param {Boolean} centeredScaling
* @returns {Boolean}
* @example
* // get
* var centeredScaling = transformer.centeredScaling();
*
* // set
* transformer.centeredScaling(true);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'centeredScaling', false);
/**
* get/set padding
* @name padding

View File

@ -1235,6 +1235,113 @@ suite('Transformer', function() {
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();
@ -1251,113 +1358,6 @@ suite('Transformer', function() {
});
layer.add(tr);
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
}
];
tests.forEach(test => {
rect.setAttrs({
x: 0,
@ -1405,4 +1405,68 @@ suite('Transformer', function() {
);
});
});
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'
);
});
});
});