changed label rect drawing from Polygon to Shape to support rounded corners soon. Also wrapped the text and rect inside of an inner group so that the label can be positioned based on the pointer tip

This commit is contained in:
Eric Rowell 2013-03-17 17:20:06 -07:00
parent bb57810c9a
commit a1f934d26a
2 changed files with 123 additions and 94 deletions

View File

@ -1,24 +1,20 @@
(function() {
// constants
var ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'padding', 'lineHeight', 'text'],
CHANGE_KINETIC = 'Change.kinetic',
NONE = 'none',
TOP = 'top',
var NONE = 'none',
UP = 'up',
RIGHT = 'right',
BOTTOM = 'bottom',
DOWN = 'down',
LEFT = 'left';
// cached variables
attrChangeListLen = ATTR_CHANGE_LIST.length;
/**
* Label constructor.  Blobs are defined by an array of points and
* a tension
* @constructor
* @param {Object} config
* @param {String} [config.arrow] can be none, top, right, bottom, or left. none is the default
* @param {Number} [config.arrowWidth]
* @param {Number} [config.arrowHeight]
* @param {String} [config.pointerDirection] can be none, up, right, down, or left. none is the default
* @param {Number} [config.pointerWidth]
* @param {Number} [config.pointerHeight]
@param {Number} [config.cornerRadius] default is 0
* @param {Object} config.text
* @param {Object} config.rect
* @param {String} [config.text.fontFamily] default is Calibri
@ -27,10 +23,7 @@
* @param {String} config.text.text
* @param {String} [config.text.align] can be left, center, or right
* @param {Number} [config.text.padding]
* @param {Number} [config.text.width] default is auto
* @param {Number} [config.text.height] default is auto
* @param {Number} [config.rect.lineHeight] default is 1
* {{ShapeParams}}
* @param {Number} [config.text.lineHeight] default is 1
* {{NodeParams}}
*/
Kinetic.Plugins.Label = function(config) {
@ -39,85 +32,120 @@
Kinetic.Plugins.Label.prototype = {
_initLabel: function(config) {
var that = this,
text = null;
this.innerGroup = new Kinetic.Group();
this.createAttrs();
Kinetic.Group.call(this, config);
this.setText(new Kinetic.Text(config.text));
text = this.getText();
this.setRect(new Kinetic.Polygon(config.rect));
this.add(this.getRect());
this.add(this.getText());
this._setPoints();
// update text data for certain attr changes
for(var n = 0; n < attrChangeListLen; n++) {
text.on(ATTR_CHANGE_LIST[n] + CHANGE_KINETIC, function() {
that._setPoints();
});
}
this.setRect(new Kinetic.Plugins.LabelRect(config.rect));
this.getRect().text = this.getText();
this.innerGroup.add(this.getRect());
this.innerGroup.add(this.getText());
this.add(this.innerGroup);
this._setGroupOffset();
},
_setPoints: function() {
_setGroupOffset: function() {
var text = this.getText(),
width = text.getWidth(),
height = text.getHeight(),
points = [],
arrow = this.getArrow(),
arrowWidth = this.getArrowWidth(),
arrowHeight = this.getArrowHeight();
// top left corner
points.push(0);
points.push(0);
if (arrow === TOP) {
points.push((width - arrowWidth)/2, 0);
points.push(width/2, -1 * arrowHeight);
points.push((width + arrowWidth)/2, 0);
}
// top right
points.push(width);
points.push(0);
rect = this.getRect(),
pointerDirection = rect.getPointerDirection(),
pointerWidth = rect.getPointerWidth(),
pointerHeight = rect.getPointerHeight(),
x = 0,
y = 0;
if (arrow === RIGHT) {
points.push(width, (height - arrowHeight)/2);
points.push(width + arrowWidth, height/2);
points.push(width, (height + arrowHeight)/2);
}
// bottom right
points.push(width);
points.push(height);
if (arrow === BOTTOM) {
points.push((width + arrowWidth)/2, height);
points.push(width/2, height + arrowHeight);
points.push((width - arrowWidth)/2, height);
}
// bottom left
points.push(0);
points.push(height);
if (arrow === LEFT) {
points.push(0, (height + arrowHeight)/2);
points.push(0 - arrowWidth, height/2);
points.push(0, (height - arrowHeight)/2);
}
this.getRect().setPoints(points);
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;
}
this.setOffset({
x: x,
y: y
});
}
};
Kinetic.Global.extend(Kinetic.Plugins.Label, Kinetic.Group);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'text');
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'rect');
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'arrow', NONE);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'arrowWidth', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'arrowHeight', 0);
})();
Kinetic.Plugins.LabelRect = function(config) {
this._initLabelRect(config);
};
Kinetic.Plugins.LabelRect.prototype = {
_initLabelRect: function(config) {
this.createAttrs();
Kinetic.Shape.call(this, config);
this.shapeType = 'LabelRect';
this._setDrawFuncs();
},
drawFunc: function(canvas) {
var context = canvas.getContext(),
width = this.text.getWidth(),
height = this.text.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();
canvas.fillStroke(this);
}
};
Kinetic.Global.extend(Kinetic.Plugins.LabelRect, Kinetic.Shape);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerDirection', NONE);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerWidth', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerHeight', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'cornerRadius', 0);
})();

View File

@ -8,29 +8,30 @@ Test.Modules.LABEL = {
var layer = new Kinetic.Layer();
var label = new Kinetic.Plugins.Label({
x: 20,
y: 20,
x: 100,
y: 100,
draggable: true,
arrow: 'left',
arrowWidth: 20,
arrowHeight: 20,
text: {
text: {
text: 'Hello World!',
fontSize: 50,
fontFamily: 'Calibri',
fontStyle: 'normal',
lineHeight: 1.2,
padding: 10,
fill: 'green',
},
fill: 'green'
},
rect: {
fill: '#bbb',
stroke: '#333',
shadowColor: 'black',
shadowBlur: 1,
shadowBlur: 10,
shadowOffset: [10, 10],
shadowOpacity: 0.2,
lineJoin: 'round'
lineJoin: 'round',
pointerDirection: 'down',
pointerWidth: 20,
pointerHeight: 20,
cornerRadius: 5
}
});