2017-12-19 15:31:36 +08:00
|
|
|
(function(Konva) {
|
|
|
|
'use strict';
|
2018-01-10 10:55:04 +08:00
|
|
|
|
2018-02-05 13:10:05 +08:00
|
|
|
var ATTR_CHANGE_LIST = [
|
|
|
|
'resizeEnabledChange',
|
|
|
|
'rotateHandlerOffsetChange'
|
|
|
|
].join(' ');
|
|
|
|
|
2018-03-15 13:11:58 +08:00
|
|
|
var NODE_RECT = 'nodeRect';
|
|
|
|
|
2018-02-05 13:10:05 +08:00
|
|
|
var TRANSFORM_CHANGE_STR = [
|
|
|
|
'xChange.resizer',
|
|
|
|
'yChange.resizer',
|
2018-02-09 15:28:19 +08:00
|
|
|
'widthChange.resizer',
|
|
|
|
'heightChange.resizer',
|
2018-02-05 13:10:05 +08:00
|
|
|
'scaleXChange.resizer',
|
|
|
|
'scaleYChange.resizer',
|
|
|
|
'skewXChange.resizer',
|
|
|
|
'skewYChange.resizer',
|
|
|
|
'rotationChange.resizer',
|
|
|
|
'offsetXChange.resizer',
|
|
|
|
'offsetYChange.resizer',
|
|
|
|
'transformsEnabledChange.resizer'
|
|
|
|
].join(' ');
|
2018-01-10 10:55:04 +08:00
|
|
|
|
2018-05-17 06:22:21 +08:00
|
|
|
var REDRAW_CHANGE_STR = [
|
|
|
|
'widthChange.resizer',
|
|
|
|
'heightChange.resizer',
|
|
|
|
'scaleXChange.resizer',
|
|
|
|
'scaleYChange.resizer',
|
|
|
|
'skewXChange.resizer',
|
|
|
|
'skewYChange.resizer',
|
|
|
|
'rotationChange.resizer',
|
|
|
|
'offsetXChange.resizer',
|
|
|
|
'offsetYChange.resizer'
|
|
|
|
].join(' ');
|
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
var ANGLES = {
|
|
|
|
'top-left': -45,
|
|
|
|
'top-center': 0,
|
|
|
|
'top-right': 45,
|
|
|
|
'middle-right': -90,
|
|
|
|
'middle-left': 90,
|
|
|
|
'bottom-left': -135,
|
|
|
|
'bottom-center': 180,
|
|
|
|
'bottom-right': 135
|
|
|
|
};
|
|
|
|
|
2018-07-03 02:04:54 +08:00
|
|
|
function getCursor(anchorName, rad, isMirrored) {
|
2018-03-07 12:40:38 +08:00
|
|
|
if (anchorName === 'rotater') {
|
|
|
|
return 'crosshair';
|
|
|
|
}
|
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
rad += Konva.Util._degToRad(ANGLES[anchorName] || 0);
|
2018-07-03 02:04:54 +08:00
|
|
|
// If we are mirrored, we need to mirror the angle (this is not the same as
|
|
|
|
// rotate).
|
|
|
|
if (isMirrored) {
|
|
|
|
rad *= -1;
|
|
|
|
}
|
2018-03-21 16:21:55 +08:00
|
|
|
var angle = (Konva.Util._radToDeg(rad) % 360 + 360) % 360;
|
2018-03-07 12:40:38 +08:00
|
|
|
|
|
|
|
if (
|
|
|
|
Konva.Util._inRange(angle, 315 + 22.5, 360) ||
|
|
|
|
Konva.Util._inRange(angle, 0, 22.5)
|
|
|
|
) {
|
|
|
|
// TOP
|
|
|
|
return 'ns-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 45 - 22.5, 45 + 22.5)) {
|
|
|
|
// TOP - RIGHT
|
|
|
|
return 'nesw-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 90 - 22.5, 90 + 22.5)) {
|
|
|
|
// RIGHT
|
|
|
|
return 'ew-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 135 - 22.5, 135 + 22.5)) {
|
|
|
|
// BOTTOM - RIGHT
|
|
|
|
return 'nwse-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 180 - 22.5, 180 + 22.5)) {
|
|
|
|
// BOTTOM
|
|
|
|
return 'ns-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 225 - 22.5, 225 + 22.5)) {
|
|
|
|
// BOTTOM - LEFT
|
|
|
|
return 'nesw-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 270 - 22.5, 270 + 22.5)) {
|
|
|
|
// RIGHT
|
|
|
|
return 'ew-resize';
|
|
|
|
} else if (Konva.Util._inRange(angle, 315 - 22.5, 315 + 22.5)) {
|
|
|
|
// BOTTOM - RIGHT
|
|
|
|
return 'nwse-resize';
|
|
|
|
} else {
|
|
|
|
// how can we can there?
|
|
|
|
// TODO: throw error
|
2018-03-21 16:21:55 +08:00
|
|
|
Konva.Util.error(
|
|
|
|
'Transformer has unknown angle for cursor detection: ' + angle
|
|
|
|
);
|
2018-03-07 12:40:38 +08:00
|
|
|
return 'pointer';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-15 13:11:58 +08:00
|
|
|
/**
|
|
|
|
* Transformer constructor. Transformer is a special type of group that allow you transform Konva
|
|
|
|
* primitives and shapes.
|
|
|
|
* @constructor
|
|
|
|
* @memberof Konva
|
|
|
|
* @param {Object} config
|
|
|
|
* @param {Boolean} [config.resizeEnabled] Default is true
|
|
|
|
* @param {Boolean} [config.rotateEnabled] Default is true
|
|
|
|
* @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is []
|
|
|
|
* @param {Number} [config.rotateHandlerOffset] Default is 50
|
2018-03-16 09:55:02 +08:00
|
|
|
* @param {Number} [config.padding] Default is 0
|
2018-03-15 13:11:58 +08:00
|
|
|
* @param {Number} [config.lineEnabled] Should we draw border? Default is true
|
|
|
|
* @param {Boolean} [config.keepRatio] Should we keep ratio when we are moving edges? Default is true
|
|
|
|
* @param {Array} [config.enabledHandlers] Array of names of enabled handles
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Function} [config.boundBoxFunc] Bounding box function
|
2018-03-15 13:11:58 +08:00
|
|
|
* @example
|
|
|
|
* var transformer = new Konva.Transformer({
|
|
|
|
* node: rectangle,
|
|
|
|
* rotateHandlerOffset: 60,
|
|
|
|
* enabledHandlers: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
|
|
|
|
* });
|
|
|
|
* layer.add(transformer);
|
|
|
|
*/
|
|
|
|
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Transformer = function(config) {
|
2017-12-19 15:31:36 +08:00
|
|
|
this.____init(config);
|
|
|
|
};
|
|
|
|
|
2018-02-01 11:25:42 +08:00
|
|
|
var RESIZERS_NAMES = [
|
|
|
|
'top-left',
|
|
|
|
'top-center',
|
|
|
|
'top-right',
|
|
|
|
'middle-right',
|
|
|
|
'middle-left',
|
|
|
|
'bottom-left',
|
|
|
|
'bottom-center',
|
|
|
|
'bottom-right'
|
|
|
|
];
|
|
|
|
|
2018-02-06 09:55:29 +08:00
|
|
|
var warningShowed = false;
|
|
|
|
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Transformer.prototype = {
|
2017-12-19 15:31:36 +08:00
|
|
|
_centroid: false,
|
|
|
|
____init: function(config) {
|
|
|
|
// call super constructor
|
|
|
|
Konva.Group.call(this, config);
|
2018-01-04 11:59:14 +08:00
|
|
|
this.className = 'Transformer';
|
2017-12-19 15:31:36 +08:00
|
|
|
this._createElements();
|
2018-02-09 15:28:19 +08:00
|
|
|
|
|
|
|
// bindings
|
2018-03-21 16:21:55 +08:00
|
|
|
this._handleMouseMove = this._handleMouseMove.bind(this);
|
|
|
|
this._handleMouseUp = this._handleMouseUp.bind(this);
|
2018-03-10 09:39:48 +08:00
|
|
|
this.update = this.update.bind(this);
|
2018-01-10 10:55:04 +08:00
|
|
|
|
|
|
|
// update transformer data for certain attr changes
|
2018-03-10 09:39:48 +08:00
|
|
|
this.on(ATTR_CHANGE_LIST, this.update);
|
2018-02-06 09:55:29 +08:00
|
|
|
|
|
|
|
if (!warningShowed) {
|
|
|
|
Konva.Util.warn(
|
2018-02-09 15:28:19 +08:00
|
|
|
'Konva.Transformer is currently experimental and may have bugs. Please report any issues to GitHub repo.'
|
2018-02-06 09:55:29 +08:00
|
|
|
);
|
|
|
|
warningShowed = true;
|
|
|
|
}
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
if (this.getNode()) {
|
|
|
|
this.update();
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
},
|
|
|
|
|
2018-06-15 15:50:36 +08:00
|
|
|
/**
|
|
|
|
* alias to `setNode`
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @returns {Konva.Transformer}
|
|
|
|
* @example
|
|
|
|
* transformer.attachTo(shape);
|
|
|
|
*/
|
2017-12-19 15:31:36 +08:00
|
|
|
attachTo: function(node) {
|
2018-03-15 13:11:58 +08:00
|
|
|
this.setNode(node);
|
|
|
|
},
|
|
|
|
|
2018-05-07 10:57:10 +08:00
|
|
|
/**
|
2018-06-15 15:50:36 +08:00
|
|
|
* attach transformer to a Konva.Node. Transformer will adapt to its size and listen its events
|
2018-05-07 10:57:10 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @returns {Konva.Transformer}
|
|
|
|
* @example
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.setNode(shape);
|
2018-05-07 10:57:10 +08:00
|
|
|
*/
|
2018-03-15 13:18:46 +08:00
|
|
|
setNode: function(node) {
|
2018-03-15 13:11:58 +08:00
|
|
|
if (this._node) {
|
2018-01-12 11:09:30 +08:00
|
|
|
this.detach();
|
|
|
|
}
|
2018-03-15 13:11:58 +08:00
|
|
|
this._node = node;
|
2018-06-15 14:12:02 +08:00
|
|
|
this._resetTransformCache();
|
2018-02-09 15:28:19 +08:00
|
|
|
|
2018-05-16 11:32:57 +08:00
|
|
|
node.on(TRANSFORM_CHANGE_STR, this._resetTransformCache.bind(this));
|
2018-05-17 06:22:21 +08:00
|
|
|
node.on(
|
|
|
|
REDRAW_CHANGE_STR,
|
|
|
|
function() {
|
|
|
|
if (!this._transforming) {
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
}.bind(this)
|
|
|
|
);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
2018-05-07 10:57:10 +08:00
|
|
|
// TODO: why do we need this?
|
2018-03-15 13:11:58 +08:00
|
|
|
var elementsCreated = !!this.findOne('.top-left');
|
|
|
|
if (elementsCreated) {
|
|
|
|
this.update();
|
|
|
|
}
|
2018-05-07 10:57:10 +08:00
|
|
|
return this;
|
2018-03-15 13:11:58 +08:00
|
|
|
},
|
|
|
|
|
2018-03-15 13:18:46 +08:00
|
|
|
getNode: function() {
|
2018-03-15 13:11:58 +08:00
|
|
|
return this._node;
|
2018-01-12 11:09:30 +08:00
|
|
|
},
|
|
|
|
|
2018-05-07 10:57:10 +08:00
|
|
|
/**
|
|
|
|
* detach transformer from a attached node
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @returns {Konva.Transformer}
|
|
|
|
* @example
|
|
|
|
* transformer.detach();
|
|
|
|
*/
|
2018-01-12 11:09:30 +08:00
|
|
|
detach: function() {
|
2018-03-15 15:11:01 +08:00
|
|
|
if (this.getNode()) {
|
|
|
|
this.getNode().off('.resizer');
|
2018-03-21 10:56:00 +08:00
|
|
|
this._node = undefined;
|
2018-03-15 15:11:01 +08:00
|
|
|
}
|
2018-05-16 11:32:57 +08:00
|
|
|
this._resetTransformCache();
|
|
|
|
},
|
|
|
|
|
|
|
|
_resetTransformCache: function() {
|
2018-03-21 10:56:00 +08:00
|
|
|
this._clearCache(NODE_RECT);
|
|
|
|
this._clearCache('transform');
|
|
|
|
this._clearSelfAndDescendantCache('absoluteTransform');
|
2018-02-09 15:28:19 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
_getNodeRect: function() {
|
2018-03-15 13:11:58 +08:00
|
|
|
return this._getCache(NODE_RECT, this.__getNodeRect);
|
|
|
|
},
|
|
|
|
|
|
|
|
__getNodeRect: function() {
|
2018-02-09 15:28:19 +08:00
|
|
|
var node = this.getNode();
|
2018-03-15 13:11:58 +08:00
|
|
|
if (!node) {
|
|
|
|
return {
|
|
|
|
x: -Number.MAX_SAFE_INTEGER,
|
|
|
|
y: -Number.MAX_SAFE_INTEGER,
|
|
|
|
width: 0,
|
|
|
|
height: 0,
|
|
|
|
rotation: 0
|
|
|
|
};
|
|
|
|
}
|
2018-02-09 15:28:19 +08:00
|
|
|
var rect = node.getClientRect({ skipTransform: true });
|
|
|
|
var rotation = Konva.getAngle(node.rotation());
|
|
|
|
|
2018-05-17 12:08:29 +08:00
|
|
|
var dx = rect.x * node.scaleX() - node.offsetX() * node.scaleX();
|
|
|
|
var dy = rect.y * node.scaleY() - node.offsetY() * node.scaleY();
|
2018-02-09 15:28:19 +08:00
|
|
|
|
|
|
|
return {
|
|
|
|
x: node.x() + dx * Math.cos(rotation) + dy * Math.sin(-rotation),
|
|
|
|
y: node.y() + dy * Math.cos(rotation) + dx * Math.sin(rotation),
|
|
|
|
width: rect.width * node.scaleX(),
|
|
|
|
height: rect.height * node.scaleY(),
|
|
|
|
rotation: node.rotation()
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
getX: function() {
|
|
|
|
return this._getNodeRect().x;
|
|
|
|
},
|
|
|
|
|
|
|
|
getY: function() {
|
|
|
|
return this._getNodeRect().y;
|
|
|
|
},
|
|
|
|
|
|
|
|
getRotation: function() {
|
|
|
|
return this._getNodeRect().rotation;
|
|
|
|
},
|
|
|
|
|
|
|
|
getWidth: function() {
|
|
|
|
return this._getNodeRect().width;
|
|
|
|
},
|
|
|
|
|
|
|
|
getHeight: function() {
|
|
|
|
return this._getNodeRect().height;
|
2017-12-19 15:31:36 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
_createElements: function() {
|
2017-12-28 09:53:57 +08:00
|
|
|
this._createBack();
|
|
|
|
|
2018-02-01 11:25:42 +08:00
|
|
|
RESIZERS_NAMES.forEach(
|
|
|
|
function(name) {
|
|
|
|
this._createAnchor(name);
|
|
|
|
}.bind(this)
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
|
|
|
this._createAnchor('rotater');
|
|
|
|
},
|
|
|
|
|
|
|
|
_createAnchor: function(name) {
|
|
|
|
var anchor = new Konva.Rect({
|
|
|
|
stroke: 'rgb(0, 161, 255)',
|
|
|
|
fill: 'white',
|
|
|
|
strokeWidth: 1,
|
|
|
|
name: name,
|
|
|
|
width: 10,
|
|
|
|
height: 10,
|
|
|
|
offsetX: 5,
|
2018-01-02 13:10:27 +08:00
|
|
|
offsetY: 5,
|
|
|
|
dragDistance: 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
|
|
|
var self = this;
|
|
|
|
anchor.on('mousedown touchstart', function(e) {
|
2018-03-21 16:21:55 +08:00
|
|
|
self._handleMouseDown(e);
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
// add hover styling
|
2018-02-10 10:28:06 +08:00
|
|
|
anchor.on('mouseenter', function() {
|
2017-12-19 15:31:36 +08:00
|
|
|
var layer = this.getLayer();
|
2018-03-21 16:21:55 +08:00
|
|
|
var tr = this.getParent();
|
|
|
|
|
|
|
|
// TODO: I guess there are some ways to simplify that calculations
|
|
|
|
// the basic idea is to find "angle" of handler
|
|
|
|
var rad = Konva.getAngle(tr.rotation());
|
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
// var cdx = tr.getWidth() / 2;
|
|
|
|
// var cdy = tr.getHeight() / 2;
|
2018-03-21 16:21:55 +08:00
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
// var parentPos = tr.getAbsolutePosition(tr.getParent());
|
|
|
|
// var center = {
|
|
|
|
// x: parentPos.x + (cdx * Math.cos(rad) + cdy * Math.sin(-rad)),
|
|
|
|
// y: parentPos.y + (cdy * Math.cos(rad) + cdx * Math.sin(rad))
|
|
|
|
// };
|
2018-03-21 16:21:55 +08:00
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
// var pos = this.getAbsolutePosition(tr.getParent());
|
2018-03-21 16:21:55 +08:00
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
// var dx = -pos.x + center.x;
|
|
|
|
// var dy = -pos.y + center.y;
|
2018-03-21 16:21:55 +08:00
|
|
|
|
2018-04-24 12:08:02 +08:00
|
|
|
// var angle = -Math.atan2(-dy, dx) - Math.PI / 2;
|
2018-07-03 02:04:54 +08:00
|
|
|
var scale = tr.getAbsoluteScale();
|
|
|
|
// If scale.y < 0 xor scale.x < 0 we need to flip (not rotate).
|
|
|
|
var isMirrored = (scale.y * scale.x) < 0;
|
|
|
|
var cursor = getCursor(name, rad, isMirrored);
|
2018-03-21 16:21:55 +08:00
|
|
|
anchor.getStage().content.style.cursor = cursor;
|
2018-03-07 12:40:38 +08:00
|
|
|
layer.batchDraw();
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
|
|
|
anchor.on('mouseout', function() {
|
|
|
|
var layer = this.getLayer();
|
2017-12-21 12:07:04 +08:00
|
|
|
if (!layer) {
|
|
|
|
return;
|
|
|
|
}
|
2018-03-21 16:21:55 +08:00
|
|
|
anchor.getStage().content.style.cursor = '';
|
2018-03-07 12:40:38 +08:00
|
|
|
layer.batchDraw();
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
|
|
|
this.add(anchor);
|
|
|
|
},
|
|
|
|
|
2017-12-28 09:53:57 +08:00
|
|
|
_createBack: function() {
|
|
|
|
var back = new Konva.Shape({
|
|
|
|
stroke: 'rgb(0, 161, 255)',
|
|
|
|
name: 'back',
|
|
|
|
width: 0,
|
|
|
|
height: 0,
|
|
|
|
listening: false,
|
|
|
|
sceneFunc: function(ctx) {
|
2018-03-16 09:55:02 +08:00
|
|
|
var tr = this.getParent();
|
|
|
|
var padding = tr.getPadding();
|
2017-12-28 09:53:57 +08:00
|
|
|
ctx.beginPath();
|
2018-03-16 09:55:02 +08:00
|
|
|
ctx.rect(
|
|
|
|
-padding,
|
|
|
|
-padding,
|
|
|
|
this.width() + padding * 2,
|
|
|
|
this.height() + padding * 2
|
|
|
|
);
|
|
|
|
ctx.moveTo(this.width() / 2, -padding);
|
|
|
|
if (tr.rotateEnabled()) {
|
2018-03-21 16:21:55 +08:00
|
|
|
ctx.lineTo(
|
|
|
|
this.width() / 2,
|
|
|
|
-tr.rotateHandlerOffset() * Konva.Util._sign(this.height())
|
|
|
|
);
|
2018-02-01 11:25:42 +08:00
|
|
|
}
|
|
|
|
|
2017-12-28 09:53:57 +08:00
|
|
|
ctx.fillStrokeShape(this);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.add(back);
|
|
|
|
},
|
|
|
|
|
2018-03-21 16:21:55 +08:00
|
|
|
_handleMouseDown: function(e) {
|
2017-12-19 15:31:36 +08:00
|
|
|
this.movingResizer = e.target.name();
|
|
|
|
|
2018-02-09 15:28:19 +08:00
|
|
|
// var node = this.getNode();
|
|
|
|
var attrs = this._getNodeRect();
|
|
|
|
var width = attrs.width;
|
|
|
|
var height = attrs.height;
|
2017-12-19 15:31:36 +08:00
|
|
|
var hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
|
|
|
|
this.sin = height / hypotenuse;
|
|
|
|
this.cos = width / hypotenuse;
|
|
|
|
|
2018-03-21 16:21:55 +08:00
|
|
|
window.addEventListener('mousemove', this._handleMouseMove);
|
|
|
|
window.addEventListener('touchmove', this._handleMouseMove);
|
2018-04-17 11:24:06 +08:00
|
|
|
window.addEventListener('mouseup', this._handleMouseUp, true);
|
|
|
|
window.addEventListener('touchend', this._handleMouseUp, true);
|
2018-02-05 13:32:48 +08:00
|
|
|
|
|
|
|
this._transforming = true;
|
2018-03-10 09:39:48 +08:00
|
|
|
|
|
|
|
this.fire('transformstart');
|
|
|
|
this.getNode().fire('transformstart');
|
2017-12-19 15:31:36 +08:00
|
|
|
},
|
|
|
|
|
2018-03-21 16:21:55 +08:00
|
|
|
_handleMouseMove: function(e) {
|
2017-12-21 10:57:16 +08:00
|
|
|
var x, y, newHypotenuse;
|
2017-12-19 15:31:36 +08:00
|
|
|
var resizerNode = this.findOne('.' + this.movingResizer);
|
|
|
|
var stage = resizerNode.getStage();
|
|
|
|
|
|
|
|
var box = stage.getContent().getBoundingClientRect();
|
|
|
|
var zeroPoint = {
|
|
|
|
x: box.left,
|
|
|
|
y: box.top
|
|
|
|
};
|
|
|
|
var pointerPos = {
|
|
|
|
left: e.clientX !== undefined ? e.clientX : e.touches[0].clientX,
|
|
|
|
top: e.clientX !== undefined ? e.clientY : e.touches[0].clientY
|
|
|
|
};
|
|
|
|
var newAbsPos = {
|
|
|
|
x: pointerPos.left - zeroPoint.x,
|
|
|
|
y: pointerPos.top - zeroPoint.y
|
|
|
|
};
|
|
|
|
|
|
|
|
resizerNode.setAbsolutePosition(newAbsPos);
|
|
|
|
|
2018-03-14 11:22:07 +08:00
|
|
|
var keepProportion = this.keepRatio() || e.shiftKey;
|
2018-03-14 11:07:55 +08:00
|
|
|
|
2017-12-19 15:31:36 +08:00
|
|
|
if (this.movingResizer === 'top-left') {
|
2018-03-14 11:07:55 +08:00
|
|
|
if (keepProportion) {
|
|
|
|
newHypotenuse = Math.sqrt(
|
|
|
|
Math.pow(this.findOne('.bottom-right').x() - resizerNode.x(), 2) +
|
|
|
|
Math.pow(this.findOne('.bottom-right').y() - resizerNode.y(), 2)
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
x = newHypotenuse * this.cos;
|
|
|
|
y = newHypotenuse * this.sin;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
this.findOne('.top-left').x(this.findOne('.bottom-right').x() - x);
|
|
|
|
this.findOne('.top-left').y(this.findOne('.bottom-right').y() - y);
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
} else if (this.movingResizer === 'top-center') {
|
|
|
|
this.findOne('.top-left').y(resizerNode.y());
|
|
|
|
} else if (this.movingResizer === 'top-right') {
|
2018-03-14 11:07:55 +08:00
|
|
|
if (keepProportion) {
|
|
|
|
newHypotenuse = Math.sqrt(
|
|
|
|
Math.pow(this.findOne('.bottom-left').x() - resizerNode.x(), 2) +
|
|
|
|
Math.pow(this.findOne('.bottom-left').y() - resizerNode.y(), 2)
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
x = newHypotenuse * this.cos;
|
|
|
|
y = newHypotenuse * this.sin;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
this.findOne('.top-right').x(x);
|
|
|
|
this.findOne('.top-right').y(this.findOne('.bottom-left').y() - y);
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
var pos = resizerNode.position();
|
|
|
|
|
|
|
|
this.findOne('.top-left').y(pos.y);
|
|
|
|
this.findOne('.bottom-right').x(pos.x);
|
|
|
|
} else if (this.movingResizer === 'middle-left') {
|
|
|
|
this.findOne('.top-left').x(resizerNode.x());
|
|
|
|
} else if (this.movingResizer === 'middle-right') {
|
|
|
|
this.findOne('.bottom-right').x(resizerNode.x());
|
|
|
|
} else if (this.movingResizer === 'bottom-left') {
|
2018-03-14 11:07:55 +08:00
|
|
|
if (keepProportion) {
|
|
|
|
newHypotenuse = Math.sqrt(
|
|
|
|
Math.pow(this.findOne('.top-right').x() - resizerNode.x(), 2) +
|
|
|
|
Math.pow(this.findOne('.top-right').y() - resizerNode.y(), 2)
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
x = newHypotenuse * this.cos;
|
|
|
|
y = newHypotenuse * this.sin;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
this.findOne('.bottom-left').x(this.findOne('.top-right').x() - x);
|
|
|
|
this.findOne('.bottom-left').y(y);
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2017-12-21 10:57:16 +08:00
|
|
|
pos = resizerNode.position();
|
2017-12-19 15:31:36 +08:00
|
|
|
|
|
|
|
this.findOne('.top-left').x(pos.x);
|
|
|
|
this.findOne('.bottom-right').y(pos.y);
|
|
|
|
} else if (this.movingResizer === 'bottom-center') {
|
|
|
|
this.findOne('.bottom-right').y(resizerNode.y());
|
|
|
|
} else if (this.movingResizer === 'bottom-right') {
|
2018-03-14 11:07:55 +08:00
|
|
|
if (keepProportion) {
|
|
|
|
newHypotenuse = Math.sqrt(
|
|
|
|
Math.pow(this.findOne('.bottom-right').x(), 2) +
|
|
|
|
Math.pow(this.findOne('.bottom-right').y(), 2)
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
x = newHypotenuse * this.cos;
|
|
|
|
y = newHypotenuse * this.sin;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-14 11:07:55 +08:00
|
|
|
this.findOne('.bottom-right').x(x);
|
|
|
|
this.findOne('.bottom-right').y(y);
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
} else if (this.movingResizer === 'rotater') {
|
2018-03-16 09:55:02 +08:00
|
|
|
var padding = this.getPadding();
|
2018-02-09 15:28:19 +08:00
|
|
|
var attrs = this._getNodeRect();
|
|
|
|
x = resizerNode.x() - attrs.width / 2;
|
|
|
|
y = -resizerNode.y() + attrs.height / 2;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
|
|
|
var dAlpha = Math.atan2(-y, x) + Math.PI / 2;
|
2018-03-21 16:21:55 +08:00
|
|
|
|
|
|
|
if (attrs.height < 0) {
|
|
|
|
dAlpha -= Math.PI;
|
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2017-12-21 11:34:29 +08:00
|
|
|
var rot = Konva.getAngle(this.rotation());
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2017-12-21 11:34:29 +08:00
|
|
|
var newRotation =
|
|
|
|
Konva.Util._radToDeg(rot) + Konva.Util._radToDeg(dAlpha);
|
|
|
|
|
2018-02-09 15:28:19 +08:00
|
|
|
var alpha = Konva.getAngle(this.getNode().rotation());
|
2017-12-19 15:31:36 +08:00
|
|
|
var newAlpha = Konva.Util._degToRad(newRotation);
|
|
|
|
|
2018-01-02 15:46:32 +08:00
|
|
|
var snaps = this.rotationSnaps();
|
|
|
|
var offset = 0.1;
|
|
|
|
for (var i = 0; i < snaps.length; i++) {
|
|
|
|
var angle = Konva.getAngle(snaps[i]);
|
|
|
|
|
|
|
|
var dif =
|
|
|
|
Math.abs(angle - Konva.Util._degToRad(newRotation)) % (Math.PI * 2);
|
|
|
|
|
|
|
|
if (dif < offset) {
|
|
|
|
newRotation = Konva.Util._radToDeg(angle);
|
|
|
|
newAlpha = Konva.Util._degToRad(newRotation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-16 09:55:02 +08:00
|
|
|
var dx = padding;
|
|
|
|
var dy = padding;
|
|
|
|
|
2018-03-21 16:21:55 +08:00
|
|
|
this._fitNodeInto({
|
|
|
|
rotation: Konva.angleDeg
|
|
|
|
? newRotation
|
|
|
|
: Konva.Util._degToRad(newRotation),
|
|
|
|
x:
|
|
|
|
attrs.x +
|
|
|
|
(attrs.width / 2 + padding) *
|
|
|
|
(Math.cos(alpha) - Math.cos(newAlpha)) +
|
|
|
|
(attrs.height / 2 + padding) *
|
|
|
|
(Math.sin(-alpha) - Math.sin(-newAlpha)) -
|
|
|
|
(dx * Math.cos(rot) + dy * Math.sin(-rot)),
|
|
|
|
y:
|
|
|
|
attrs.y +
|
|
|
|
(attrs.height / 2 + padding) *
|
|
|
|
(Math.cos(alpha) - Math.cos(newAlpha)) +
|
|
|
|
(attrs.width / 2 + padding) *
|
|
|
|
(Math.sin(alpha) - Math.sin(newAlpha)) -
|
|
|
|
(dy * Math.cos(rot) + dx * Math.sin(rot)),
|
|
|
|
width: attrs.width + padding * 2,
|
|
|
|
height: attrs.height + padding * 2
|
|
|
|
});
|
2017-12-19 15:31:36 +08:00
|
|
|
} else {
|
|
|
|
console.error(
|
|
|
|
new Error(
|
|
|
|
'Wrong position argument of selection resizer: ',
|
|
|
|
this.movingResizer
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.movingResizer === 'rotater') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-07 12:24:48 +08:00
|
|
|
var absPos = this.findOne('.top-left').getAbsolutePosition(
|
|
|
|
this.getParent()
|
|
|
|
);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2017-12-21 10:57:16 +08:00
|
|
|
x = absPos.x;
|
|
|
|
y = absPos.y;
|
|
|
|
var width =
|
|
|
|
this.findOne('.bottom-right').x() - this.findOne('.top-left').x();
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2017-12-21 10:57:16 +08:00
|
|
|
var height =
|
|
|
|
this.findOne('.bottom-right').y() - this.findOne('.top-left').y();
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-02-09 15:28:19 +08:00
|
|
|
this._fitNodeInto({
|
|
|
|
x: x + this.offsetX(),
|
|
|
|
y: y + this.offsetY(),
|
2017-12-19 15:31:36 +08:00
|
|
|
width: width,
|
|
|
|
height: height
|
2017-12-21 10:57:16 +08:00
|
|
|
});
|
2017-12-19 15:31:36 +08:00
|
|
|
},
|
|
|
|
|
2018-03-21 16:21:55 +08:00
|
|
|
_handleMouseUp: function() {
|
2018-02-05 13:32:48 +08:00
|
|
|
this._removeEvents();
|
|
|
|
},
|
|
|
|
|
|
|
|
_removeEvents: function() {
|
|
|
|
if (this._transforming) {
|
2018-02-10 10:35:43 +08:00
|
|
|
this._transforming = false;
|
2018-03-21 16:21:55 +08:00
|
|
|
window.removeEventListener('mousemove', this._handleMouseMove);
|
|
|
|
window.removeEventListener('touchmove', this._handleMouseMove);
|
2018-04-17 11:24:06 +08:00
|
|
|
window.removeEventListener('mouseup', this._handleMouseUp, true);
|
|
|
|
window.removeEventListener('touchend', this._handleMouseUp, true);
|
2018-02-10 10:35:43 +08:00
|
|
|
this.fire('transformend');
|
|
|
|
this.getNode().fire('transformend');
|
2018-02-05 13:32:48 +08:00
|
|
|
}
|
2017-12-19 15:31:36 +08:00
|
|
|
},
|
|
|
|
|
2018-04-11 09:36:08 +08:00
|
|
|
_fitNodeInto: function(newAttrs) {
|
2018-03-16 09:55:02 +08:00
|
|
|
// waring! in this attrs padding may be included
|
2018-04-11 09:36:08 +08:00
|
|
|
var boundBoxFunc = this.getBoundBoxFunc();
|
|
|
|
if (boundBoxFunc) {
|
|
|
|
var oldAttrs = this._getNodeRect();
|
|
|
|
newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs);
|
|
|
|
}
|
2018-02-09 15:28:19 +08:00
|
|
|
this._settings = true;
|
|
|
|
var node = this.getNode();
|
2018-04-11 09:36:08 +08:00
|
|
|
if (newAttrs.rotation !== undefined) {
|
|
|
|
this.getNode().rotation(newAttrs.rotation);
|
2017-12-19 15:31:36 +08:00
|
|
|
}
|
2018-02-09 15:28:19 +08:00
|
|
|
var pure = node.getClientRect({ skipTransform: true });
|
2018-03-16 09:55:02 +08:00
|
|
|
var padding = this.getPadding();
|
2018-04-11 09:36:08 +08:00
|
|
|
var scaleX = (newAttrs.width - padding * 2) / pure.width;
|
|
|
|
var scaleY = (newAttrs.height - padding * 2) / pure.height;
|
2018-02-09 15:28:19 +08:00
|
|
|
|
|
|
|
var rotation = Konva.getAngle(node.getRotation());
|
2018-05-17 12:08:29 +08:00
|
|
|
var dx = pure.x * scaleX - padding - node.offsetX() * scaleX;
|
|
|
|
var dy = pure.y * scaleY - padding - node.offsetY() * scaleY;
|
2018-02-18 11:45:24 +08:00
|
|
|
|
2018-02-09 15:28:19 +08:00
|
|
|
this.getNode().setAttrs({
|
|
|
|
scaleX: scaleX,
|
|
|
|
scaleY: scaleY,
|
2018-04-11 09:36:08 +08:00
|
|
|
x: newAttrs.x - (dx * Math.cos(rotation) + dy * Math.sin(-rotation)),
|
|
|
|
y: newAttrs.y - (dy * Math.cos(rotation) + dx * Math.sin(rotation))
|
2018-02-09 15:28:19 +08:00
|
|
|
});
|
|
|
|
this._settings = false;
|
|
|
|
|
2018-02-01 11:25:42 +08:00
|
|
|
this.fire('transform');
|
2018-02-09 15:28:19 +08:00
|
|
|
this.getNode().fire('transform');
|
2018-03-10 09:39:48 +08:00
|
|
|
this.update();
|
2017-12-19 15:31:36 +08:00
|
|
|
this.getLayer().batchDraw();
|
|
|
|
},
|
2018-03-15 13:18:46 +08:00
|
|
|
/**
|
2018-05-07 10:57:10 +08:00
|
|
|
* force update of Konva.Transformer.
|
|
|
|
* Use it when you updated attached Konva.Group and now you need to reset transformer size
|
2018-03-15 13:18:46 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
*/
|
2018-03-15 13:11:58 +08:00
|
|
|
forceUpdate: function() {
|
2018-05-16 11:32:57 +08:00
|
|
|
this._resetTransformCache();
|
2018-03-15 13:11:58 +08:00
|
|
|
this.update();
|
|
|
|
},
|
2018-03-10 09:39:48 +08:00
|
|
|
update: function() {
|
2018-02-09 15:28:19 +08:00
|
|
|
var attrs = this._getNodeRect();
|
|
|
|
var width = attrs.width;
|
|
|
|
var height = attrs.height;
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-03-15 13:11:58 +08:00
|
|
|
var enabledHandlers = this.enabledHandlers();
|
2018-01-02 13:25:36 +08:00
|
|
|
var resizeEnabled = this.resizeEnabled();
|
2018-03-16 09:55:02 +08:00
|
|
|
var padding = this.getPadding();
|
2017-12-28 09:32:00 +08:00
|
|
|
|
|
|
|
this.findOne('.top-left').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: -padding,
|
|
|
|
y: -padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.top-center').setAttrs({
|
2017-12-19 15:31:36 +08:00
|
|
|
x: width / 2,
|
2018-03-16 09:55:02 +08:00
|
|
|
y: -padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.top-right').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: width + padding,
|
|
|
|
y: -padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.middle-left').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: -padding,
|
2017-12-28 09:32:00 +08:00
|
|
|
y: height / 2,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.middle-right').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: width + padding,
|
2017-12-28 09:32:00 +08:00
|
|
|
y: height / 2,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.bottom-left').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: -padding,
|
|
|
|
y: height + padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.bottom-center').setAttrs({
|
2017-12-19 15:31:36 +08:00
|
|
|
x: width / 2,
|
2018-03-16 09:55:02 +08:00
|
|
|
y: height + padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.bottom-right').setAttrs({
|
2018-03-16 09:55:02 +08:00
|
|
|
x: width + padding,
|
|
|
|
y: height + padding,
|
2018-03-15 13:11:58 +08:00
|
|
|
visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
|
|
|
|
2017-12-28 09:32:00 +08:00
|
|
|
this.findOne('.rotater').setAttrs({
|
2017-12-19 15:31:36 +08:00
|
|
|
x: width / 2,
|
2018-03-21 16:21:55 +08:00
|
|
|
y: -this.rotateHandlerOffset() * Konva.Util._sign(height),
|
2018-02-01 11:25:42 +08:00
|
|
|
visible: this.rotateEnabled()
|
2017-12-19 15:31:36 +08:00
|
|
|
});
|
2017-12-28 09:53:57 +08:00
|
|
|
|
|
|
|
this.findOne('.back').setAttrs({
|
|
|
|
width: width,
|
2018-02-05 13:10:05 +08:00
|
|
|
height: height,
|
|
|
|
visible: this.lineEnabled()
|
2017-12-28 09:53:57 +08:00
|
|
|
});
|
2017-12-21 12:07:04 +08:00
|
|
|
},
|
2018-05-07 10:57:10 +08:00
|
|
|
/**
|
|
|
|
* determine if transformer is in active transform
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
2018-04-11 09:36:08 +08:00
|
|
|
isTransforming: function() {
|
|
|
|
return this._transforming;
|
|
|
|
},
|
2018-05-07 10:57:10 +08:00
|
|
|
/**
|
|
|
|
* Stop active transform action
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
2018-04-11 09:36:08 +08:00
|
|
|
stopTransform: function() {
|
|
|
|
if (this._transforming) {
|
|
|
|
this._removeEvents();
|
|
|
|
}
|
|
|
|
},
|
2017-12-21 12:07:04 +08:00
|
|
|
destroy: function() {
|
|
|
|
Konva.Group.prototype.destroy.call(this);
|
2018-03-15 15:11:01 +08:00
|
|
|
this.detach();
|
2018-02-05 13:32:48 +08:00
|
|
|
this._removeEvents();
|
2018-03-15 13:11:58 +08:00
|
|
|
},
|
|
|
|
// do not work as a container
|
|
|
|
// we will recreate inner nodes manually
|
|
|
|
toObject: function() {
|
|
|
|
return Konva.Node.prototype.toObject.call(this);
|
2017-12-19 15:31:36 +08:00
|
|
|
}
|
|
|
|
};
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Util.extend(Konva.Transformer, Konva.Group);
|
2017-12-19 15:31:36 +08:00
|
|
|
|
2018-02-05 13:10:05 +08:00
|
|
|
function validateResizers(val) {
|
|
|
|
if (!(val instanceof Array)) {
|
2018-03-15 13:11:58 +08:00
|
|
|
Konva.Util.warn('enabledHandlers value should be an array');
|
2018-02-05 13:10:05 +08:00
|
|
|
}
|
|
|
|
if (val instanceof Array) {
|
|
|
|
val.forEach(function(name) {
|
2018-02-18 11:45:24 +08:00
|
|
|
if (RESIZERS_NAMES.indexOf(name) === -1) {
|
2018-02-05 13:10:05 +08:00
|
|
|
Konva.Util.warn(
|
|
|
|
'Unknown resizer name: ' +
|
|
|
|
name +
|
|
|
|
'. Available names are: ' +
|
|
|
|
RESIZERS_NAMES.join(', ')
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return val || [];
|
|
|
|
}
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set enabled handlers
|
|
|
|
* @name enabledHandlers
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @param {Array} array
|
|
|
|
* @returns {Array}
|
|
|
|
* @example
|
|
|
|
* // get list of handlers
|
2018-06-15 15:50:36 +08:00
|
|
|
* var enabledHandlers = transformer.enabledHandlers();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set handlers
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.enabledHandlers(['top-left', 'top-center', 'top-right', 'middle-right', 'middle-left', 'bottom-left', 'bottom-center', 'bottom-right']);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-02-01 11:25:42 +08:00
|
|
|
Konva.Factory.addGetterSetter(
|
|
|
|
Konva.Transformer,
|
2018-03-15 13:11:58 +08:00
|
|
|
'enabledHandlers',
|
2018-02-01 11:25:42 +08:00
|
|
|
RESIZERS_NAMES,
|
2018-02-05 13:10:05 +08:00
|
|
|
validateResizers
|
2018-02-01 11:25:42 +08:00
|
|
|
);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set resize ability. If false it will automatically hide resizing handlers
|
|
|
|
* @name resizeEnabled
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @param {Array} array
|
|
|
|
* @returns {Array}
|
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var resizeEnabled = transformer.resizeEnabled();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.resizeEnabled(false);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'resizeEnabled', true);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set ability to rotate.
|
|
|
|
* @name rotateEnabled
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Boolean} enabled
|
|
|
|
* @returns {Boolean}
|
2018-03-15 13:11:58 +08:00
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var rotateEnabled = transformer.rotateEnabled();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.rotateEnabled(false);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-02-01 11:25:42 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotateEnabled', true);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set rotation snaps angles.
|
|
|
|
* @name rotationSnaps
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @param {Array} array
|
|
|
|
* @returns {Array}
|
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var rotationSnaps = transformer.rotationSnaps();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.rotationSnaps([0, 90, 180, 270]);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotationSnaps', []);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set distance for rotation handler
|
|
|
|
* @name rotateHandlerOffset
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Number} offset
|
|
|
|
* @returns {Number}
|
2018-03-15 13:11:58 +08:00
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var rotateHandlerOffset = transformer.rotateHandlerOffset();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.rotateHandlerOffset(100);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-01-10 10:44:22 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotateHandlerOffset', 50);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set visibility of border
|
|
|
|
* @name lineEnabled
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Boolean} enabled
|
|
|
|
* @returns {Boolean}
|
2018-03-15 13:11:58 +08:00
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var lineEnabled = transformer.lineEnabled();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.lineEnabled(false);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-02-05 13:10:05 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'lineEnabled', true);
|
2018-03-15 13:11:58 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get/set should we keep ration of resize?
|
|
|
|
* @name keepRatio
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Boolean} keepRatio
|
|
|
|
* @returns {Boolean}
|
2018-03-15 13:11:58 +08:00
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var keepRatio = transformer.keepRatio();
|
2018-03-15 13:11:58 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.keepRatio(false);
|
2018-03-15 13:11:58 +08:00
|
|
|
*/
|
2018-03-14 11:22:07 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
|
2018-03-14 11:07:55 +08:00
|
|
|
|
2018-03-16 09:55:02 +08:00
|
|
|
/**
|
|
|
|
* get/set padding
|
|
|
|
* @name padding
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
2018-06-15 15:50:36 +08:00
|
|
|
* @param {Number} padding
|
|
|
|
* @returns {Number}
|
2018-03-16 09:55:02 +08:00
|
|
|
* @example
|
|
|
|
* // get
|
2018-06-15 15:50:36 +08:00
|
|
|
* var padding = transformer.padding();
|
2018-03-16 09:55:02 +08:00
|
|
|
*
|
|
|
|
* // set
|
2018-06-15 15:50:36 +08:00
|
|
|
* transformer.padding(10);
|
2018-03-16 09:55:02 +08:00
|
|
|
*/
|
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'padding', 0);
|
|
|
|
|
2018-03-15 13:11:58 +08:00
|
|
|
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
|
2017-12-28 09:32:00 +08:00
|
|
|
|
2018-06-15 15:50:36 +08:00
|
|
|
/**
|
|
|
|
* get/set bounding box function
|
|
|
|
* @name boundBoxFunc
|
|
|
|
* @method
|
|
|
|
* @memberof Konva.Transformer.prototype
|
|
|
|
* @param {Function} func
|
|
|
|
* @returns {Function}
|
|
|
|
* @example
|
|
|
|
* // get
|
|
|
|
* var boundBoxFunc = transformer.boundBoxFunc();
|
|
|
|
*
|
|
|
|
* // set
|
|
|
|
* transformer.boundBoxFunc(function(oldBox, newBox) {
|
|
|
|
* if (newBox.width > 200) {
|
|
|
|
* return oldBox;
|
|
|
|
* }
|
|
|
|
* return newBox;
|
|
|
|
* });
|
|
|
|
*/
|
2018-04-11 09:36:08 +08:00
|
|
|
Konva.Factory.addGetterSetter(Konva.Transformer, 'boundBoxFunc');
|
|
|
|
|
2018-01-04 11:59:14 +08:00
|
|
|
Konva.Collection.mapMethods(Konva.Transformer);
|
2017-12-19 15:31:36 +08:00
|
|
|
})(Konva);
|