mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
299 lines
8.6 KiB
JavaScript
299 lines
8.6 KiB
JavaScript
(function() {
|
|
// constants
|
|
var ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'padding', 'lineHeight', 'text'],
|
|
CHANGE_KINETIC = 'Change.kinetic',
|
|
NONE = 'none',
|
|
UP = 'up',
|
|
RIGHT = 'right',
|
|
DOWN = 'down',
|
|
LEFT = 'left',
|
|
LABEL = 'Label',
|
|
|
|
// cached variables
|
|
attrChangeListLen = ATTR_CHANGE_LIST.length;
|
|
|
|
/**
|
|
* Label constructor. Labels are groups that contain a Text and Tag shape
|
|
* @constructor
|
|
* @memberof Kinetic
|
|
* @param {Object} config
|
|
* @@nodeParams
|
|
* @example
|
|
* // create label
|
|
* var label = new Kinetic.Label({<br>
|
|
* x: 100,<br>
|
|
* y: 100, <br>
|
|
* draggable: true<br>
|
|
* });<br><br>
|
|
*
|
|
* // add a tag to the label<br>
|
|
* label.add(new Kinetic.Tag({<br>
|
|
* fill: '#bbb',<br>
|
|
* stroke: '#333',<br>
|
|
* shadowColor: 'black',<br>
|
|
* shadowBlur: 10,<br>
|
|
* shadowOffset: [10, 10],<br>
|
|
* shadowOpacity: 0.2,<br>
|
|
* lineJoin: 'round',<br>
|
|
* pointerDirection: 'up',<br>
|
|
* pointerWidth: 20,<br>
|
|
* pointerHeight: 20,<br>
|
|
* cornerRadius: 5<br>
|
|
* }));<br><br>
|
|
*
|
|
* // add text to the label<br>
|
|
* label.add(new Kinetic.Text({<br>
|
|
* text: 'Hello World!',<br>
|
|
* fontSize: 50,<br>
|
|
* lineHeight: 1.2,<br>
|
|
* padding: 10,<br>
|
|
* fill: 'green'<br>
|
|
* }));
|
|
*/
|
|
Kinetic.Label = function(config) {
|
|
this.____init(config);
|
|
};
|
|
|
|
Kinetic.Label.prototype = {
|
|
____init: function(config) {
|
|
var that = this;
|
|
|
|
this.className = LABEL;
|
|
Kinetic.Group.call(this, config);
|
|
|
|
this.on('add.kinetic', function(evt) {
|
|
that._addListeners(evt.child);
|
|
that._sync();
|
|
});
|
|
},
|
|
/**
|
|
* get Text shape for the label. You need to access the Text shape in order to update
|
|
* the text properties
|
|
* @name getText
|
|
* @method
|
|
* @memberof Kinetic.Label.prototype
|
|
*/
|
|
getText: function() {
|
|
return this.find('Text')[0];
|
|
},
|
|
/**
|
|
* get Tag shape for the label. You need to access the Tag shape in order to update
|
|
* the pointer properties and the corner radius
|
|
* @name getTag
|
|
* @method
|
|
* @memberof Kinetic.Label.prototype
|
|
*/
|
|
getTag: function() {
|
|
return this.find('Tag')[0];
|
|
},
|
|
_addListeners: function(text) {
|
|
var that = this,
|
|
n;
|
|
var func = function(){
|
|
that._sync();
|
|
};
|
|
|
|
// update text data for certain attr changes
|
|
for(n = 0; n < attrChangeListLen; n++) {
|
|
text.on(ATTR_CHANGE_LIST[n] + CHANGE_KINETIC, func);
|
|
}
|
|
},
|
|
getWidth: function() {
|
|
return this.getText().getWidth();
|
|
},
|
|
getHeight: function() {
|
|
return this.getText().getHeight();
|
|
},
|
|
_sync: function() {
|
|
var text = this.getText(),
|
|
tag = this.getTag(),
|
|
width, height, pointerDirection, pointerWidth, x, y;
|
|
|
|
if (text && tag) {
|
|
width = text.getWidth(),
|
|
height = text.getHeight(),
|
|
pointerDirection = tag.getPointerDirection(),
|
|
pointerWidth = tag.getPointerWidth(),
|
|
pointerHeight = tag.getPointerHeight(),
|
|
x = 0,
|
|
y = 0;
|
|
|
|
switch(pointerDirection) {
|
|
case UP:
|
|
x = width / 2;
|
|
y = -1 * pointerHeight;
|
|
break;
|
|
case RIGHT:
|
|
x = width + pointerWidth;
|
|
y = height / 2;
|
|
break;
|
|
case DOWN:
|
|
x = width / 2;
|
|
y = height + pointerHeight;
|
|
break;
|
|
case LEFT:
|
|
x = -1 * pointerWidth;
|
|
y = height / 2;
|
|
break;
|
|
}
|
|
|
|
tag.setAttrs({
|
|
x: -1 * x,
|
|
y: -1 * y,
|
|
width: width,
|
|
height: height
|
|
});
|
|
|
|
text.setAttrs({
|
|
x: -1 * x,
|
|
y: -1 * y
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
Kinetic.Util.extend(Kinetic.Label, Kinetic.Group);
|
|
|
|
Kinetic.Collection.mapMethods(Kinetic.Label);
|
|
|
|
/**
|
|
* Tag constructor. A Tag can be configured
|
|
* to have a pointer element that points up, right, down, or left
|
|
* @constructor
|
|
* @memberof Kinetic
|
|
* @param {Object} config
|
|
* @param {String} [config.pointerDirection] can be up, right, down, left, or none; the default
|
|
* is none. When a pointer is present, the positioning of the label is relative to the tip of the pointer.
|
|
* @param {Number} [config.pointerWidth]
|
|
* @param {Number} [config.pointerHeight]
|
|
* @param {Number} [config.cornerRadius]
|
|
*/
|
|
Kinetic.Tag = function(config) {
|
|
this.___init(config);
|
|
};
|
|
|
|
Kinetic.Tag.prototype = {
|
|
___init: function(config) {
|
|
Kinetic.Shape.call(this, config);
|
|
this.className = 'Tag';
|
|
this.sceneFunc(this._sceneFunc);
|
|
},
|
|
_sceneFunc: function(context) {
|
|
var width = this.getWidth(),
|
|
height = this.getHeight(),
|
|
pointerDirection = this.getPointerDirection(),
|
|
pointerWidth = this.getPointerWidth(),
|
|
pointerHeight = this.getPointerHeight(),
|
|
cornerRadius = this.getCornerRadius();
|
|
|
|
context.beginPath();
|
|
context.moveTo(0,0);
|
|
|
|
if (pointerDirection === UP) {
|
|
context.lineTo((width - pointerWidth)/2, 0);
|
|
context.lineTo(width/2, -1 * pointerHeight);
|
|
context.lineTo((width + pointerWidth)/2, 0);
|
|
}
|
|
|
|
context.lineTo(width, 0);
|
|
|
|
if (pointerDirection === RIGHT) {
|
|
context.lineTo(width, (height - pointerHeight)/2);
|
|
context.lineTo(width + pointerWidth, height/2);
|
|
context.lineTo(width, (height + pointerHeight)/2);
|
|
}
|
|
|
|
context.lineTo(width, height);
|
|
|
|
if (pointerDirection === DOWN) {
|
|
context.lineTo((width + pointerWidth)/2, height);
|
|
context.lineTo(width/2, height + pointerHeight);
|
|
context.lineTo((width - pointerWidth)/2, height);
|
|
}
|
|
|
|
context.lineTo(0, height);
|
|
|
|
if (pointerDirection === LEFT) {
|
|
context.lineTo(0, (height + pointerHeight)/2);
|
|
context.lineTo(-1 * pointerWidth, height/2);
|
|
context.lineTo(0, (height - pointerHeight)/2);
|
|
}
|
|
|
|
context.closePath();
|
|
context.fillStrokeShape(this);
|
|
}
|
|
};
|
|
|
|
Kinetic.Util.extend(Kinetic.Tag, Kinetic.Shape);
|
|
Kinetic.Factory.addGetterSetter(Kinetic.Tag, 'pointerDirection', NONE);
|
|
|
|
/**
|
|
* set pointer Direction
|
|
* @name setPointerDirection
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
* @param {String} pointerDirection can be up, right, down, left, or none. The
|
|
* default is none
|
|
*/
|
|
|
|
/**
|
|
* get pointer Direction
|
|
* @name getPointerDirection
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
*/
|
|
|
|
Kinetic.Factory.addGetterSetter(Kinetic.Tag, 'pointerWidth', 0);
|
|
|
|
/**
|
|
* set pointer width
|
|
* @name setPointerWidth
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
* @param {Number} pointerWidth
|
|
*/
|
|
|
|
/**
|
|
* get pointer width
|
|
* @name getPointerWidth
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
*/
|
|
|
|
Kinetic.Factory.addGetterSetter(Kinetic.Tag, 'pointerHeight', 0);
|
|
|
|
/**
|
|
* set pointer height
|
|
* @name setPointerHeight
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
* @param {Number} pointerHeight
|
|
*/
|
|
|
|
/**
|
|
* get pointer height
|
|
* @name getPointerHeight
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
*/
|
|
|
|
Kinetic.Factory.addGetterSetter(Kinetic.Tag, 'cornerRadius', 0);
|
|
|
|
/**
|
|
* set corner radius
|
|
* @name setCornerRadius
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
* @param {Number} corner radius
|
|
*/
|
|
|
|
/**
|
|
* get corner radius
|
|
* @name getCornerRadius
|
|
* @method
|
|
* @memberof Kinetic.Tag.prototype
|
|
*/
|
|
|
|
Kinetic.Collection.mapMethods(Kinetic.Tag);
|
|
})();
|