Fabric.js: Can't use setBackgroundImage for full size backgrounds

Created on 15 Nov 2018  路  2Comments  路  Source: fabricjs/fabric.js

I am trying to load a background image into my fabric canvas (v2.4.3). My canvas is square (600x600px), so is my background image (say 1000x1000px). None of the methods described here http://fabricjs.com/docs/fabric.StaticCanvas.html#setBackgroundImage work to stretch the background image to full canvas size.
The only way that does work, is:

fabric.Image.fromURL('background.jpg', function(img) {
   img.scaleToWidth(canvas.width);
   img.scaleToHeight(canvas.height);
   canvas.setBackgroundImage(img);
   canvas.requestRenderAll();
});

But there's a problem with this approach.
I save this canvas with canvas.toJSON(). Then I want to reload this json into a fresh fabric canvas, and then the background image is off, just by a few pixels, but very noticable. It's just rounding errors I think, but the effect is very visible.
With fabric 1.x, you could do:

canvas.setBackgroundImage(
   'background.jpg',
      function() {
         canvas.renderAll();
      },
      {
         width: canvas.width,
         height: canvas.height,
         originX: 'left',
         originY: 'top'
       }
);

Saving & reloading the JSON would work without issues, no rounding issues.

docs

Most helpful comment

fabric.Image.fromURL('background.jpg', function(img) {
   img.scaleToWidth(canvas.width);
   img.scaleToHeight(canvas.height);
   canvas.setBackgroundImage(img);
   canvas.requestRenderAll();
});

You can't really apply scaleToWidth and scaleToHeight, one will override the other.

You can calculate the scaling each dimension:

image.scaleX = canvas.width / img.width;
image.scaleY = canvas.height / img.height;

For the JSON do not restore correctly please make a search on stackOverflow for NUM_FRACTION_DIGITS, if it does not solve prepare a fiddle where the problem is clearly visible.

All 2 comments

fabric.Image.fromURL('background.jpg', function(img) {
   img.scaleToWidth(canvas.width);
   img.scaleToHeight(canvas.height);
   canvas.setBackgroundImage(img);
   canvas.requestRenderAll();
});

You can't really apply scaleToWidth and scaleToHeight, one will override the other.

You can calculate the scaling each dimension:

image.scaleX = canvas.width / img.width;
image.scaleY = canvas.height / img.height;

For the JSON do not restore correctly please make a search on stackOverflow for NUM_FRACTION_DIGITS, if it does not solve prepare a fiddle where the problem is clearly visible.

Yup, setting NUM_FRACTION_DIGITS works. Thanks!
For others landing here, here's how to make fractions more exact:
fabric.Object.NUM_FRACTION_DIGITS = 10;

One last request: please fix the documentation at http://fabricjs.com/docs/fabric.StaticCanvas.html#setBackgroundImage
Both stretched examples listed there do not work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guettli picture guettli  路  4Comments

lyzs90 picture lyzs90  路  3Comments

medialwerk picture medialwerk  路  5Comments

raichu picture raichu  路  4Comments

keanass picture keanass  路  5Comments