Fabric JS _updateObjectsCoords alternative ? (Migration issue to 1.7.9)

enter image description here

I am trying to make my curveText function work (see bottom of this post). It normally works with fabric.js 1.2.0 however when I updated to fabric.js 1.7.9, the curving function locates the text in wrong positions when below two actions executed sequentially.

ACTIONS : – ISSUE 1

-text group scale is changed (I mean dragging the corner points by mouse to change size).

-setText called

fabric js 1.2.0:

fabric js 1.7.9

I debugged it and the reason for that is _updateObjectsCoords in fabricjs because when I removed it from the code and 2 actions I listed above works fine.

ISSUE 2:
But this time I have faced below problem which is group items are not correctly located when adding the text to canvas for the first time.

with _updateObjectsCoords

enter image description here

without _updateObjectsCoords

enter image description here

Here My Function:

var CurvedText = (function() {
function CurvedText( canvas, options ){
    this.opts = options || {};
    for ( var prop in CurvedText.defaults ) {
        if (prop in this.opts) { continue; }
        this.opts[prop] = CurvedText.defaults[prop];
    }

    this.canvas = canvas;
    this.group = new fabric.Group([], {selectable: this.opts.selectable,name:'arc',radiusVal:this.opts.radius,spacingVal:this.opts.spacing,textFliping:this.opts.reverse,itemName:'text'});
    this.canvas.add( this.group ) ;
    this.canvas.centerObject( this.group );
    this._forceGroupUpdate();
    this.setText( this.opts.text );
    this.canvas.setActiveObject( this.group );
    this.canvas.getActiveObject().setCoords();

}

CurvedText.prototype.set = function( param, value, obj ) {
    this.group = obj;
    this.opts.top=this.group.top;
    this.opts.left=this.group.left;

    if ( this.opts[param] !== undefined ) {
        this.opts[param] = value;
        if ( param === 'fontSize' || param === 'fontWeight' || param === 'fontFamily' || param === 'fontColor' ) {
            this.opts.textStyleName = param;
            this._setFontStyles();
        }
        if ( param === 'selectable' ) {
            this.group.selectable = value;
        }
        if ( param === 'angle' ) {
            this._forceGroupUpdate();
        }
        if( param === 'radius' || param === 'spacing' )
        {
            this.group.radiusVal = this.opts.radius;
            this.group.spacingVal = this.opts.spacing;
        }
        if ( param === 'reverse' ) {
            this.group.textFliping = this.opts.reverse;
        }

        this._render();
        return true;
    } else {
        return false;
    }
};

CurvedText.prototype.get = function( param ) {
    this._render();
    if ( this.opts[param] !== undefined ) {
        return this.opts[param];
    } else {
        return false;
    }
};

CurvedText.prototype.getParams = function() {
    this._render();
    return this.opts;
};

CurvedText.prototype.center = function() {
    this.opts.top = this.canvas.height / 2;
    this.opts.left = this.canvas.width / 2;
    this._render();
    return { top:this.opts.top, left:this.opts.left };
};

CurvedText.prototype.remove = function() {
    var size = this.group.size();
    for ( var i=size; i>=0; i-- ){
        this.group.remove( this.group.item(i) );
    }
    this.canvas.renderAll();
};

CurvedText.prototype.setObj = function(obj) 
{
    this.group=obj;
};

CurvedText.prototype.setText = function( newText ) {

    this.opts.top=this.group.top;
    this.opts.left=this.group.left;

    while ( newText.length !== 0 && this.group.size() > newText.length ) {
        this.group.remove( this.group.item( this.group.size()-1 ) );
    }

    for ( var i=0; i<newText.length; i++ ){
        if ( this.group.item(i) === undefined ){
            var letter = new fabric.Text(newText[i], {
                selectable: true
            });
            this.group.add( letter );
        }
        else{
            this.group.item(i).text = newText[i];
        }
    }
    this.opts.text = newText;
    this._setFontStyles();
    this._render();
};

CurvedText.prototype._setFontStyles = function() {
    for ( var i=0; i<this.group.size(); i++ ){
        if( this.opts.textStyleName )
        {
            if( this.opts.textStyleName === 'fontFamily' )
            {
                this.group.item(i).setFontFamily( this.opts.fontFamily );
            }
            if( this.opts.textStyleName === 'fontColor' )
            {
                this.group.item(i).setFill( this.opts.fontColor );
            }
        }
        else
        {
            this.group.item(i).setFontFamily( this.opts.fontFamily );
            this.group.item(i).setFill( this.opts.fontColor );
        }
        this.group.item(i).setFontSize( this.opts.fontSize );
        this.group.item(i).fontWeight = this.opts.fontWeight ;
    }
};

CurvedText.prototype._forceGroupUpdate = function() {
    this.group.setAngle( this.opts.angle );
    this.group.scaleX = this.opts.scaleX;
    this.group.scaleY = this.opts.scaleY;
    this._render();
};

CurvedText.prototype._render = function() {
    var curAngle=0,angleRadians=0, align=0;

    // Object may have been moved with drag&drop
    if ( this.group.hasMoved() ) {
        this.opts.top = this.group.top;
        this.opts.left = this.group.left;
    }
    this.opts.angle = this.group.getAngle();
    this.opts.scaleX = this.group.scaleX;
    this.opts.scaleY = this.group.scaleY;
    this.opts.radius = this.group.radiusVal;
    this.opts.spacing = this.group.spacingVal;
    this.opts.reverse = this.group.textFliping;


    // Text align
    if ( this.opts.align === 'center' ) {
        align = ( this.opts.spacing / 2) * ( this.group.size() - 1) ;
    } else if ( this.opts.align === 'right' ) {
        align = ( this.opts.spacing ) * ( this.group.size() - 1) ;
    }

    for ( var i=0; i<this.group.size(); i++) {
        // Find coords of each letters (radians : angle*(Math.PI / 180)
        if ( this.opts.reverse ) {
            curAngle = (-i * parseInt( this.opts.spacing, 10 )) + align;
            angleRadians = curAngle * (Math.PI / 180);
            this.group.item(i).setAngle( curAngle );

            this.group.item(i).set( 'top', (Math.cos( angleRadians ) * this.opts.radius) );
            this.group.item(i).set( 'left', (-Math.sin( angleRadians ) * this.opts.radius) );
        } else {
            curAngle = (i * parseInt( this.opts.spacing, 10)) - align;
            angleRadians = curAngle * (Math.PI / 180);
            this.group.item(i).setAngle( curAngle );

            this.group.item(i).set( 'top', (-Math.cos( angleRadians ) * this.opts.radius) );
            this.group.item(i).set( 'left', (Math.sin( angleRadians ) * this.opts.radius) ) ;
        }
        this.group.item(i).setAngle( curAngle );
    }

    // Update group coords
    this.group._calcBounds();
    this.group.top = this.opts.top;
    this.group.left = this.opts.left;
    this.group.saveCoords();

    this.canvas.renderAll();
};

CurvedText.defaults = {
    top: 0,
    left: 0,
    scaleX: 1,
    scaleY: 1,
    angle: 0,
    spacing:0,
    radius:0,
    text: '',
    align: 'center',
    reverse:'',
    fontSize:16,
    fontWeight: 'normal',
    selectable: true,
    fontFamily:'',
    fontColor:'',
    textStyleName:''
};

return CurvedText;})();

Read more here: Fabric JS _updateObjectsCoords alternative ? (Migration issue to 1.7.9)

Leave a Reply

Your email address will not be published. Required fields are marked *