bugs fixes

This commit is contained in:
Anton Lavrenov 2018-03-15 12:11:58 +07:00
parent d50b0fe1ea
commit 2e878aa79b
2 changed files with 255 additions and 25 deletions

View File

@ -6,6 +6,8 @@
'rotateHandlerOffsetChange'
].join(' ');
var NODE_RECT = 'nodeRect';
var TRANSFORM_CHANGE_STR = [
'xChange.resizer',
'yChange.resizer',
@ -75,6 +77,31 @@
}
}
/**
* Transformer constructor. Transformer is a special type of group that allow you transform Konva
* primitives and shapes.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @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
* @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
* @@nodeParams
* @@containerParams
* @example
* var transformer = new Konva.Transformer({
* node: rectangle,
* rotateHandlerOffset: 60,
* enabledHandlers: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
* });
* layer.add(transformer);
*/
Konva.Transformer = function(config) {
this.____init(config);
};
@ -114,17 +141,39 @@
);
warningShowed = true;
}
if (this.getNode()) {
this.update();
}
},
attachTo: function(node) {
if (this.node()) {
this.setNode(node);
},
setNode(node) {
if (this._node) {
this.detach();
}
this.setNode(node);
node.on('dragmove.resizer', this.update);
node.on(TRANSFORM_CHANGE_STR, this.update);
this._node = node;
this.update();
node.on(
TRANSFORM_CHANGE_STR,
function() {
this._clearCache(NODE_RECT);
}.bind(this)
);
node.on(TRANSFORM_CHANGE_STR, this.requestUpdate.bind(this));
node.on('dragmove.resizer', this.requestUpdate);
var elementsCreated = !!this.findOne('.top-left');
if (elementsCreated) {
this.update();
}
},
getNode() {
return this._node;
},
detach: function() {
@ -132,7 +181,20 @@
},
_getNodeRect: function() {
return this._getCache(NODE_RECT, this.__getNodeRect);
},
__getNodeRect: function() {
var node = this.getNode();
if (!node) {
return {
x: -Number.MAX_SAFE_INTEGER,
y: -Number.MAX_SAFE_INTEGER,
width: 0,
height: 0,
rotation: 0
};
}
var rect = node.getClientRect({ skipTransform: true });
var rotation = Konva.getAngle(node.rotation());
@ -484,6 +546,23 @@
this.update();
this.getLayer().batchDraw();
},
requestUpdate: function() {
if (this.timeout) {
return;
}
this.timeout = setTimeout(
function() {
this.timeout = null;
this.update();
}.bind(this)
);
},
forceUpdate: function() {
this._clearCache(NODE_RECT);
this.update();
},
update: function() {
var attrs = this._getNodeRect();
var x = attrs.x;
@ -494,48 +573,48 @@
this.y(y);
this.rotation(attrs.rotation);
var enabledResizers = this.enabledResizers();
var enabledHandlers = this.enabledHandlers();
var resizeEnabled = this.resizeEnabled();
this.findOne('.top-left').setAttrs({
x: 0,
y: 0,
visible: resizeEnabled && enabledResizers.indexOf('top-left') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('top-left') >= 0
});
this.findOne('.top-center').setAttrs({
x: width / 2,
y: 0,
visible: resizeEnabled && enabledResizers.indexOf('top-center') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('top-center') >= 0
});
this.findOne('.top-right').setAttrs({
x: width,
y: 0,
visible: resizeEnabled && enabledResizers.indexOf('top-right') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('top-right') >= 0
});
this.findOne('.middle-left').setAttrs({
x: 0,
y: height / 2,
visible: resizeEnabled && enabledResizers.indexOf('middle-left') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('middle-left') >= 0
});
this.findOne('.middle-right').setAttrs({
x: width,
y: height / 2,
visible: resizeEnabled && enabledResizers.indexOf('middle-right') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('middle-right') >= 0
});
this.findOne('.bottom-left').setAttrs({
x: 0,
y: height,
visible: resizeEnabled && enabledResizers.indexOf('bottom-left') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('bottom-left') >= 0
});
this.findOne('.bottom-center').setAttrs({
x: width / 2,
y: height,
visible: resizeEnabled && enabledResizers.indexOf('bottom-center') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('bottom-center') >= 0
});
this.findOne('.bottom-right').setAttrs({
x: width,
y: height,
visible: resizeEnabled && enabledResizers.indexOf('bottom-right') >= 0
visible: resizeEnabled && enabledHandlers.indexOf('bottom-right') >= 0
});
this.findOne('.rotater').setAttrs({
@ -554,13 +633,18 @@
Konva.Group.prototype.destroy.call(this);
this.getNode().off('.resizer');
this._removeEvents();
},
// do not work as a container
// we will recreate inner nodes manually
toObject: function() {
return Konva.Node.prototype.toObject.call(this);
}
};
Konva.Util.extend(Konva.Transformer, Konva.Group);
function validateResizers(val) {
if (!(val instanceof Array)) {
Konva.Util.warn('enabledResizers value should be an array');
Konva.Util.warn('enabledHandlers value should be an array');
}
if (val instanceof Array) {
val.forEach(function(name) {
@ -576,25 +660,125 @@
}
return val || [];
}
/**
* get/set enabled handlers
* @name enabledHandlers
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get list of handlers
* var enabledHandlers = shape.enabledHandlers();
*
* // set handlers
* shape.enabledHandlers(['top-left', 'top-center', 'top-right', 'middle-right', 'middle-left', 'bottom-left', 'bottom-center', 'bottom-right']);
*/
Konva.Factory.addGetterSetter(
Konva.Transformer,
'enabledResizers',
RESIZERS_NAMES
);
Konva.Factory.addGetterSetter(
Konva.Transformer,
'enabledResizers',
'enabledHandlers',
RESIZERS_NAMES,
validateResizers
);
/**
* 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
* var resizeEnabled = shape.resizeEnabled();
*
* // set
* shape.resizeEnabled(false);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'resizeEnabled', true);
/**
* get/set ability to rotate.
* @name rotateEnabled
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var rotateEnabled = shape.rotateEnabled();
*
* // set
* shape.rotateEnabled(false);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotateEnabled', true);
/**
* get/set rotation snaps angles.
* @name rotationSnaps
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var rotationSnaps = shape.rotationSnaps();
*
* // set
* shape.rotationSnaps([0, 90, 180, 270]);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotationSnaps', []);
/**
* get/set distance for rotation handler
* @name rotateHandlerOffset
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var rotateHandlerOffset = shape.rotateHandlerOffset();
*
* // set
* shape.rotateHandlerOffset(100);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'rotateHandlerOffset', 50);
/**
* get/set visibility of border
* @name lineEnabled
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var lineEnabled = shape.lineEnabled();
*
* // set
* shape.lineEnabled(false);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'lineEnabled', true);
/**
* get/set should we keep ration of resize?
* @name keepRatio
* @method
* @memberof Konva.Transformer.prototype
* @param {Array} array
* @returns {Array}
* @example
* // get
* var keepRatio = shape.keepRatio();
*
* // set
* shape.keepRatio(false);
*/
Konva.Factory.addGetterSetter(Konva.Transformer, 'keepRatio', true);
Konva.Factory.addGetterSetter(Konva.Transformer, 'node');
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
Konva.Collection.mapMethods(Konva.Transformer);
})(Konva);

View File

@ -15,9 +15,10 @@ suite('Transformer', function() {
});
layer.add(rect);
var tr = new Konva.Transformer();
var tr = new Konva.Transformer({
node: rect
});
layer.add(tr);
tr.attachTo(rect);
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
@ -26,6 +27,12 @@ suite('Transformer', function() {
assert.equal(tr.y(), rect.y());
assert.equal(tr.width(), rect.width());
assert.equal(tr.height(), rect.height());
// manual check of correct position of node
var handler = tr.findOne('.bottom-right');
var pos = handler.getAbsolutePosition();
assert.equal(pos.x, rect.x() + rect.width());
assert.equal(pos.y, rect.y() + rect.height());
});
test('try to fit simple rectangle', function() {
@ -541,7 +548,7 @@ suite('Transformer', function() {
assert.equal(tr.rotation(), 0);
});
test('fit group', function() {
test.only('fit group', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
@ -596,4 +603,43 @@ suite('Transformer', function() {
assert.equal(tr.width(), 200);
assert.equal(tr.height(), 100);
});
test('toJSON should not save attached node and children', function() {
var stage = addStage();
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'
});
layer.add(rect);
var tr = new Konva.Transformer();
layer.add(tr);
tr.attachTo(rect);
layer.draw();
var json = tr.toJSON();
var object = JSON.parse(json);
assert.equal(object.attrs.node, undefined);
assert.equal(object.children, undefined);
});
test('make sure we can work without inner node', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var tr = new Konva.Transformer();
layer.add(tr);
layer.draw();
});
});