add possibility for top,right,bottom and left rotation anchors

This commit is contained in:
Thomas Uher 2022-04-27 14:24:58 +02:00
parent 81cf46c18a
commit 13f6eba657
3 changed files with 188 additions and 43 deletions

View File

@ -8,7 +8,7 @@
* Konva JavaScript Framework v8.3.5 * Konva JavaScript Framework v8.3.5
* http://konvajs.org/ * http://konvajs.org/
* Licensed under the MIT * Licensed under the MIT
* Date: Mon Apr 11 2022 * Date: Wed Apr 27 2022
* *
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva) * Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
@ -370,17 +370,6 @@
getMatrix() { getMatrix() {
return this.m; return this.m;
} }
/**
* set to absolute position via translation
* @method
* @name Konva.Transform#setAbsolutePosition
* @returns {Konva.Transform}
* @author ericdrowell
*/
setAbsolutePosition(x, y) {
var m0 = this.m[0], m1 = this.m[1], m2 = this.m[2], m3 = this.m[3], m4 = this.m[4], m5 = this.m[5], yt = (m0 * (y - m5) - m1 * (x - m4)) / (m0 * m3 - m1 * m2), xt = (x - m4 - m2 * yt) / m0;
return this.translate(xt, yt);
}
/** /**
* convert transformation matrix back into node's attributes * convert transformation matrix back into node's attributes
* @method * @method
@ -14526,7 +14515,7 @@
}; };
const TOUCH_DEVICE = 'ontouchstart' in Konva$2._global; const TOUCH_DEVICE = 'ontouchstart' in Konva$2._global;
function getCursor(anchorName, rad) { function getCursor(anchorName, rad) {
if (anchorName === 'rotater') { if (anchorName.indexOf('rotater') === 0) {
return 'crosshair'; return 'crosshair';
} }
rad += Util.degToRad(ANGLES[anchorName] || 0); rad += Util.degToRad(ANGLES[anchorName] || 0);
@ -14578,6 +14567,10 @@
'bottom-left', 'bottom-left',
'bottom-center', 'bottom-center',
'bottom-right', 'bottom-right',
'rotater-top',
'rotater-bottom',
'rotater-left',
'rotater-right'
]; ];
var MAX_SAFE_INTEGER = 100000000; var MAX_SAFE_INTEGER = 100000000;
function getCenter(shape) { function getCenter(shape) {
@ -14909,7 +14902,6 @@
ANCHORS_NAMES.forEach(function (name) { ANCHORS_NAMES.forEach(function (name) {
this._createAnchor(name); this._createAnchor(name);
}.bind(this)); }.bind(this));
this._createAnchor('rotater');
} }
_createAnchor(name) { _createAnchor(name) {
var anchor = new Rect({ var anchor = new Rect({
@ -14960,9 +14952,24 @@
var padding = tr.padding(); var padding = tr.padding();
ctx.beginPath(); ctx.beginPath();
ctx.rect(-padding, -padding, this.width() + padding * 2, this.height() + padding * 2); ctx.rect(-padding, -padding, this.width() + padding * 2, this.height() + padding * 2);
ctx.moveTo(this.width() / 2, -padding);
if (tr.rotateEnabled()) { if (tr.rotateEnabled()) {
ctx.lineTo(this.width() / 2, -tr.rotateAnchorOffset() * Util._sign(this.height()) - padding); var enabledAnchors = tr.enabledAnchors();
if (enabledAnchors.indexOf('rotater-top') >= 0) {
ctx.moveTo(this.width() / 2, -padding);
ctx.lineTo(this.width() / 2, -tr.rotateAnchorOffset() * Util._sign(this.height()) - padding);
}
if (enabledAnchors.indexOf('rotater-bottom') >= 0) {
ctx.moveTo(this.width() / 2, this.height() + padding);
ctx.lineTo(this.width() / 2, this.height() + tr.rotateAnchorOffset() * Util._sign(this.height()) - padding);
}
if (enabledAnchors.indexOf('rotater-left') >= 0) {
ctx.moveTo(-padding, this.height() / 2);
ctx.lineTo(-tr.rotateAnchorOffset() * Util._sign(this.width()) - padding, this.height() / 2);
}
if (enabledAnchors.indexOf('rotater-right') >= 0) {
ctx.moveTo(this.width() + padding, this.height() / 2);
ctx.lineTo(this.width() + tr.rotateAnchorOffset() * Util._sign(this.width()) + padding, this.height() / 2);
}
} }
ctx.fillStrokeShape(this); ctx.fillStrokeShape(this);
}, },
@ -15042,12 +15049,37 @@
return; return;
} }
// rotater is working very differently, so do it first // rotater is working very differently, so do it first
if (this._movingAnchorName === 'rotater') { if (this._movingAnchorName.indexOf('rotater') === 0) {
var attrs = this._getNodeRect(); var attrs = this._getNodeRect();
x = anchorNode.x() - attrs.width / 2; var delta;
y = -anchorNode.y() + attrs.height / 2; if (this._movingAnchorName.indexOf('rotater') === 0) {
// hor angle is changed? var attrs = this._getNodeRect();
let delta = Math.atan2(-y, x) + Math.PI / 2; if (this._movingAnchorName.indexOf('top') >= 0) {
x = anchorNode.x() - attrs.width / 2;
y = -anchorNode.y() + attrs.height / 2;
delta = Math.atan2(-y, x) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('bottom') >= 0) {
x = -anchorNode.x() + attrs.width / 2;
y = anchorNode.y() - attrs.height / 2;
delta = Math.atan2(-y, x) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('left') >= 0) {
x = anchorNode.x() - attrs.width / 2;
y = -anchorNode.y() + attrs.height / 2;
delta = Math.atan2(x, y) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('right') >= 0) {
x = -anchorNode.x() + attrs.width / 2;
y = anchorNode.y() - attrs.height / 2;
delta = Math.atan2(x, y) + Math.PI / 2;
}
else {
console.error(new Error('Wrong position argument of rotater: ' +
this._movingAnchorName));
return;
}
}
if (attrs.height < 0) { if (attrs.height < 0) {
delta -= Math.PI; delta -= Math.PI;
} }
@ -15273,7 +15305,8 @@
} }
if (this._movingAnchorName && if (this._movingAnchorName &&
newAttrs.height < 0 && newAttrs.height < 0 &&
this._movingAnchorName.indexOf('top') >= 0) { this._movingAnchorName.indexOf('top') >= 0 &&
this._movingAnchorName.indexOf('rotater') == -1) {
const offset = t.point({ const offset = t.point({
x: 0, x: 0,
y: -this.padding() * 2, y: -this.padding() * 2,
@ -15291,7 +15324,8 @@
} }
else if (this._movingAnchorName && else if (this._movingAnchorName &&
newAttrs.height < 0 && newAttrs.height < 0 &&
this._movingAnchorName.indexOf('bottom') >= 0) { this._movingAnchorName.indexOf('bottom') >= 0 &&
this._movingAnchorName.indexOf('rotater') == -1) {
const offset = t.point({ const offset = t.point({
x: 0, x: 0,
y: this.padding() * 2, y: this.padding() * 2,
@ -15450,10 +15484,25 @@
offsetY: anchorSize / 2 - padding, offsetY: anchorSize / 2 - padding,
visible: resizeEnabled && enabledAnchors.indexOf('bottom-right') >= 0, visible: resizeEnabled && enabledAnchors.indexOf('bottom-right') >= 0,
}); });
this._batchChangeChild('.rotater', { this._batchChangeChild('.rotater-top', {
x: width / 2, x: width / 2,
y: -this.rotateAnchorOffset() * Util._sign(height) - padding, y: -this.rotateAnchorOffset() * Util._sign(height) - padding,
visible: this.rotateEnabled(), visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-top') >= 0,
});
this._batchChangeChild('.rotater-bottom', {
x: width / 2,
y: height + this.rotateAnchorOffset() * Util._sign(height) - padding,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-bottom') >= 0,
});
this._batchChangeChild('.rotater-left', {
x: -this.rotateAnchorOffset() - padding,
y: height / 2,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-left') >= 0,
});
this._batchChangeChild('.rotater-right', {
x: width + this.rotateAnchorOffset() - padding,
y: height / 2,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-right') >= 0,
}); });
this._batchChangeChild('.back', { this._batchChangeChild('.back', {
width: width, width: width,

4
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -92,7 +92,7 @@ var ANGLES = {
const TOUCH_DEVICE = 'ontouchstart' in Konva._global; const TOUCH_DEVICE = 'ontouchstart' in Konva._global;
function getCursor(anchorName, rad) { function getCursor(anchorName, rad) {
if (anchorName === 'rotater') { if (anchorName.indexOf('rotater') === 0) {
return 'crosshair'; return 'crosshair';
} }
@ -139,6 +139,10 @@ var ANCHORS_NAMES = [
'bottom-left', 'bottom-left',
'bottom-center', 'bottom-center',
'bottom-right', 'bottom-right',
'rotater-top',
'rotater-bottom',
'rotater-left',
'rotater-right'
]; ];
var MAX_SAFE_INTEGER = 100000000; var MAX_SAFE_INTEGER = 100000000;
@ -523,7 +527,6 @@ export class Transformer extends Group {
}.bind(this) }.bind(this)
); );
this._createAnchor('rotater');
} }
_createAnchor(name) { _createAnchor(name) {
var anchor = new Rect({ var anchor = new Rect({
@ -580,15 +583,59 @@ export class Transformer extends Group {
this.width() + padding * 2, this.width() + padding * 2,
this.height() + padding * 2 this.height() + padding * 2
); );
ctx.moveTo(this.width() / 2, -padding);
if (tr.rotateEnabled()) { if (tr.rotateEnabled()) {
ctx.lineTo(
this.width() / 2, var enabledAnchors = tr.enabledAnchors();
-tr.rotateAnchorOffset() * Util._sign(this.height()) - padding
); if (enabledAnchors.indexOf('rotater-top') >= 0) {
ctx.moveTo(this.width() / 2, -padding);
ctx.lineTo(
this.width() / 2,
-tr.rotateAnchorOffset() * Util._sign(this.height()) - padding
);
}
if (enabledAnchors.indexOf('rotater-bottom') >= 0) {
ctx.moveTo(this.width() / 2, this.height() + padding);
ctx.lineTo(
this.width() / 2,
this.height() + tr.rotateAnchorOffset() * Util._sign(this.height()) - padding
);
}
if (enabledAnchors.indexOf('rotater-left') >= 0) {
ctx.moveTo(-padding, this.height() / 2);
ctx.lineTo(
-tr.rotateAnchorOffset() * Util._sign(this.width()) - padding,
this.height() / 2
);
}
if (enabledAnchors.indexOf('rotater-right') >= 0) {
ctx.moveTo(this.width() + padding, this.height() / 2);
ctx.lineTo(
this.width() + tr.rotateAnchorOffset() * Util._sign(this.width()) + padding,
this.height() / 2
);
}
} }
ctx.fillStrokeShape(this); ctx.fillStrokeShape(this);
}, },
hitFunc: (ctx, shape) => { hitFunc: (ctx, shape) => {
if (!this.shouldOverdrawWholeArea()) { if (!this.shouldOverdrawWholeArea()) {
@ -681,13 +728,42 @@ export class Transformer extends Group {
} }
// rotater is working very differently, so do it first // rotater is working very differently, so do it first
if (this._movingAnchorName === 'rotater') { if (this._movingAnchorName.indexOf('rotater') === 0) {
var attrs = this._getNodeRect(); var attrs = this._getNodeRect();
x = anchorNode.x() - attrs.width / 2;
y = -anchorNode.y() + attrs.height / 2;
// hor angle is changed? var delta : number;
let delta = Math.atan2(-y, x) + Math.PI / 2;
if (this._movingAnchorName.indexOf('rotater') === 0) {
var attrs = this._getNodeRect();
if (this._movingAnchorName.indexOf('top') >= 0) {
x = anchorNode.x() - attrs.width / 2;
y = -anchorNode.y() + attrs.height / 2;
delta = Math.atan2(-y, x) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('bottom') >= 0) {
x = -anchorNode.x() + attrs.width / 2;
y = anchorNode.y() - attrs.height / 2;
delta = Math.atan2(-y, x) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('left') >= 0) {
x = anchorNode.x() - attrs.width / 2;
y = -anchorNode.y() + attrs.height / 2;
delta = Math.atan2(x, y) + Math.PI / 2;
}
else if (this._movingAnchorName.indexOf('right') >= 0) {
x = -anchorNode.x() + attrs.width / 2;
y = anchorNode.y() - attrs.height / 2;
delta = Math.atan2(x, y) + Math.PI / 2;
}
else {
console.error(new Error('Wrong position argument of rotater: ' +
this._movingAnchorName));
return;
}
}
if (attrs.height < 0) { if (attrs.height < 0) {
delta -= Math.PI; delta -= Math.PI;
@ -971,7 +1047,8 @@ export class Transformer extends Group {
if ( if (
this._movingAnchorName && this._movingAnchorName &&
newAttrs.height < 0 && newAttrs.height < 0 &&
this._movingAnchorName.indexOf('top') >= 0 this._movingAnchorName.indexOf('top') >= 0 &&
this._movingAnchorName.indexOf('rotater') == -1
) { ) {
const offset = t.point({ const offset = t.point({
x: 0, x: 0,
@ -990,7 +1067,8 @@ export class Transformer extends Group {
} else if ( } else if (
this._movingAnchorName && this._movingAnchorName &&
newAttrs.height < 0 && newAttrs.height < 0 &&
this._movingAnchorName.indexOf('bottom') >= 0 this._movingAnchorName.indexOf('bottom') >= 0 &&
this._movingAnchorName.indexOf('rotater') == -1
) { ) {
const offset = t.point({ const offset = t.point({
x: 0, x: 0,
@ -1162,10 +1240,28 @@ export class Transformer extends Group {
visible: resizeEnabled && enabledAnchors.indexOf('bottom-right') >= 0, visible: resizeEnabled && enabledAnchors.indexOf('bottom-right') >= 0,
}); });
this._batchChangeChild('.rotater', { this._batchChangeChild('.rotater-top', {
x: width / 2, x: width / 2,
y: -this.rotateAnchorOffset() * Util._sign(height) - padding, y: -this.rotateAnchorOffset() * Util._sign(height) - padding,
visible: this.rotateEnabled(), visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-top') >= 0,
});
this._batchChangeChild('.rotater-bottom', {
x: width / 2,
y: height + this.rotateAnchorOffset() * Util._sign(height) - padding,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-bottom') >= 0,
});
this._batchChangeChild('.rotater-left', {
x: - this.rotateAnchorOffset() - padding,
y: height / 2 ,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-left') >= 0,
});
this._batchChangeChild('.rotater-right', {
x: width + this.rotateAnchorOffset() - padding,
y: height / 2,
visible: this.rotateEnabled() && enabledAnchors.indexOf('rotater-right') >= 0,
}); });
this._batchChangeChild('.back', { this._batchChangeChild('.back', {