我创建了一个扩展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);
  }
});


但是结果不是我想要的。

结果 :

javascript - Fabric.js自定义类的边框和背景-LMLPHP

我要那个 :

javascript - Fabric.js自定义类的边框和背景-LMLPHP

提前致谢。

最佳答案

我找到了解决方案:

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);
    }
});

09-25 15:15