mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 07:25:56 +08:00
bugs fixes
This commit is contained in:
parent
d50b0fe1ea
commit
2e878aa79b
@ -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);
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user