2

When cloning an image with Fabric.js, the size of the cloned image and the original image will be different.

The code is scripted down below. You can check the movements by pressing “Run code snippet”. Click on the canvas after uploading the image to clone it. Click again to make the clone image disappear. Repeating the clicks makes it easy to check the image size error.

const canvas = new fabric.Canvas("c");

$("input").on("change", e => {
    canvas.clear();
    const fr = new FileReader(e);
    fr.onload = (e) => {
        input(e.target.result);
    };
    fr.readAsDataURL(e.target.files[0]);
});

const input = url => {
    fabric.Image.fromURL(url, oImg => {
        canvas.setWidth($("html").width());
        const resizeScale = canvas.width / oImg.width;
        oImg.scale(resizeScale);
        canvas.setHeight(oImg.height * resizeScale);
        canvas.add(oImg).renderAll();
        canvas.selection = oImg.selectable = false;
    });
};

$("canvas").mousedown(() => {
    const obj = canvas.getObjects();
    if (obj.length === 1) {
        const oImg = obj[0];
        oImg.clone(copy => {
            canvas.add(copy).renderAll();
        });
    };
    if (obj.length === 2) {
        const cloneImg = obj[1];
        canvas.remove(cloneImg);
    };
});
html {
  max-width: 1080px;
  width: 100%;
  margin: auto;
  text-align: center;
}

canvas{
  border: 1px solid black;
}

.canvas-container {
  margin: auto;
}
<input type="file" accept="image/*">
<canvas id="c"></canvas>

<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.3.2/fabric.min.js"></script>

I want to know how to match the size of the clone image to the original image.

Also, the larger the original image size, the greater the error occurs a lot more. I’ve prepared a test image in the link, so feel free to download and use it.

smallImg

bigImg

Jay White
  • 315
  • 1
  • 3
  • 10

1 Answers1

2

clone() and toObject() methods round numeric properties (scale, position, angle, etc.) to 2 decimals by default. This is determined by fabric.Object.NUM_FRACTION_DIGITS.

So the original image could have, say, a scaleX of 1.857421875 while the clone ends up with 1.86, hence the difference in the resulting size.

There are several ways you can fix this:

1) Re-set the scale each time after making a clone, e.g.

oImg.clone(copy => {
    copy.set({
      scaleX: oImg.scaleX,
      scaleY: oImg.scaleY,
    });
    canvas.add(copy).renderAll();
});

2) Change the default precision

fabric.Object.NUM_FRACTION_DIGITS = 5
shkaper
  • 4,689
  • 1
  • 22
  • 35