我创建了一个扩展IText的类,我想绘制一个类似于选择的边框。
下面的类代码:(fiddle exemple)
var LabeledBubble = fabric.util.createClass(fabric.IText,{
type: 'labeledBubble',
initialize: function(options) {
options || (options = {});
this.callSuper('initialize',options);
this.set('bubbleType',options.bubbleType || 'Rect');
this.set('backColor',options.backColor || '#FFF');
this.set('borderColor',options.borderColor || '#000');
this.set('borderWidth',options.borderWidth || 1);
this.set('borderDash',options.borderDash || []);
this.textAlign = "center";
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'),{
bubbleType: this.get('bubbleType')
});
},
_render: function(ctx,noTransform) {
var w = this.width,
h = this.height,
x = noTransform ? this.left : -this.width / 2,
y = noTransform ? this.top : -this.height / 2;
ctx.save();
ctx.fillStyle = "#FF0000";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 2;
ctx.fillRect(x, y, w, h);
ctx.strokeRect(x, y, w, h);
ctx.restore();
this.callSuper('_render',ctx);
}
});
但是结果不是我想要的。
结果 :
我要那个 :
提前致谢。
最佳答案
我找到了解决方案:
var LabeledBubble = fabric.util.createClass(fabric.IText,{
type: 'labeledBubble',
initialize: function(options) {
options || (options = {});
this.callSuper('initialize',options);
this.set('bubbleType',options.bubbleType || 'Rect');
this.set('backColor',options.backColor || '#FFF');
this.set('borderColor',options.borderColor || '#000');
this.set('borderWidth',options.borderWidth || 1);
this.set('borderDash',options.borderDash || []);
this.textAlign = "center";
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'),{
bubbleType: this.get('bubbleType')
});
},
_initDimensions: function(ctx) {
if(this.__skipDimension) {
return;
}
if(!ctx) {
ctx = fabric.util.createCanvasElement().getContext('2d');
this._setTextStyles(ctx);
}
this._textLines = this._splitTextIntoLines();
this._clearCache();
this.width = (this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH) + 5; // here add 5 pix
this.height = this._getTextHeight(ctx) + 5; // here add 5 pix
},
renderCursorOrSelection: function() {
if(!this.active || !this.isEditing) {
return;
}
var chars = this.text.split(''),
boundaries,ctx;
if(this.canvas && this.canvas.contextTop) {
ctx = this.canvas.contextTop;
ctx.save();
ctx.transform.apply(ctx,this.canvas.viewportTransform);
this.transform(ctx);
this.transformMatrix && ctx.transform.apply(ctx,this.transformMatrix);
this._clearTextArea(ctx);
}
else {
ctx = this.ctx;
ctx.save();
}
ctx.translate(0,2); // here add 2 pix for spacing
if(this.selectionStart === this.selectionEnd) {
boundaries = this._getCursorBoundaries(chars,'cursor');
this.renderCursor(boundaries,ctx);
}
else {
boundaries = this._getCursorBoundaries(chars,'selection');
this.renderSelection(chars,boundaries,ctx);
}
ctx.restore();
},
_renderText: function(ctx) {
ctx.save();
ctx.translate(0,2); // here add 2 pix for spacing
this._renderTextFill(ctx);
this._renderTextStroke(ctx);
ctx.restore();
},
_render: function(ctx,noTransform) {
var w = this.width,
h = this.height,
x = noTransform ? this.left : -this.width / 2,
y = noTransform ? this.top : -this.height / 2;
ctx.save();
ctx.fillStyle = this.backColor;
ctx.strokeStyle = this.borderColor;
ctx.lineWidth = this.borderWidth;
switch(this.bubbleType) {
case "Circle":
ctx.arc(0,0,bounds.width > bounds.height ? bounds.width * .5 : bounds.height * .5,0,2 * Math.PI);
break;
case "DoubleCircle":
break;
default:
ctx.rect(x,y,w,h);
}
this._renderFill(ctx);
this._renderStroke(ctx);
ctx.restore();
this.callSuper('_render',ctx);
}
});