Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading from JSON - Objects not scaled?

My guess is that this is something I'm doing wrong....

Saving and loading Fabric drawings using the toJSON and fromJSON methods, and it seems that scaled objects don't retain their scaling.

FYI, the PNG files it creates look right.

So, here's what the image looks like when I save it: Good Pic

Then, when I reload it: Bad Pic

Code:

function save () {
    // Need to clear selection and remove overlay before saving.
    canvas.deactivateAll();
    if (!mask) {canvas.setOverlayImage('', canvas.renderAll.bind(canvas));}
    // If they're zoomed in, reset the image
    resetZoom();
    var name = prompt("Please enter a filename", "NewPresentation");
    var url = 'http://localhost/fabric/img/'+name+'.png';
    var stat = checkUrl(url);
    //console.log("Stat: "+stat);
    if (stat) {
        if (!confirm(url+" already exists. Do you want to overwrite the existing file?")) return false;
    }

    $.ajax({
        type: 'POST',
        url: 'save.php',
        data: {
            task: 'save', 
            img: canvas.toDataURL('png'),
            json: JSON.stringify(canvas.toJSON()),
            name: name, 
            coid: companyId,
            id: ''
        },
        success: function(json) {
            if (!json.success) {
                alert('Error!'); return;
                currPresId = json.id;
            }
        }
       });
    if (!mask) {canvas.setOverlayImage('dist/pixelmask.png', canvas.renderAll.bind(canvas));}
    list();
}

Load Routine:

function loadPresentation(id) {
    console.log("We should be loading "+id);
    $.ajax({
        type: 'GET',
        url: 'loadPresentation.php',
        data: {
            id: id
        },
        success: function(json) {
            console.log("Success");
            var j = JSON.parse(json);
            canvas.loadFromJSON(j);
        }
    });
}

Can anyone point out to me what I might be doing that would cause this? Thanks in advance for your help. If I didn't give you something you need to troubleshoot, LMK, and I'll get it up here shortly.

like image 975
Jason Maggard Avatar asked Aug 15 '26 18:08

Jason Maggard


1 Answers

Figured it out...

The scaleX/scaleY numbers are rounded.

From JSON: scaleX: 0.05

The actual scale is scaleX: 0.05203252032520325

Looking at the fabric.js code:

toObject: function(propertiesToInclude) {

      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,

          object = {
            type:               this.type,
            originX:            this.originX,
            originY:            this.originY,
            left:               toFixed(this.left, NUM_FRACTION_DIGITS),
            top:                toFixed(this.top, NUM_FRACTION_DIGITS),
            width:              toFixed(this.width, NUM_FRACTION_DIGITS),
            height:             toFixed(this.height, NUM_FRACTION_DIGITS),
            fill:               (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,
            stroke:             (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,
            strokeWidth:        toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),
            strokeDashArray:    this.strokeDashArray,
            strokeLineCap:      this.strokeLineCap,
            strokeLineJoin:     this.strokeLineJoin,
            strokeMiterLimit:   toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
            scaleX:             toFixed(this.scaleX, NUM_FRACTION_DIGITS),
            scaleY:             toFixed(this.scaleY, NUM_FRACTION_DIGITS),
            angle:              toFixed(this.getAngle(), NUM_FRACTION_DIGITS),
            flipX:              this.flipX,
            flipY:              this.flipY,
            opacity:            toFixed(this.opacity, NUM_FRACTION_DIGITS),
            shadow:             (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,
            visible:            this.visible,
            clipTo:             this.clipTo && String(this.clipTo),
            backgroundColor:    this.backgroundColor
          };

So, the easy thing to do is to set the NUM_FRACTION_DIGITS:

canvas = new fabric.Canvas('canvas', {width: w, height: h});
canvas.setBackgroundColor($('#bgcolor').val(), canvas.renderAll.bind(canvas));
fabric.Object.NUM_FRACTION_DIGITS = 17;

Now the scale is saved properly. Hope this helps someone else out down the road.

like image 137
Jason Maggard Avatar answered Aug 18 '26 08:08

Jason Maggard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!