Fabric JS group selection and scaling messing up individual object position attributes

Viewed 289

I am trying to achieve a function so that every object on the canvas scales down in size equally and center them on the canvas (in order to add some space / padding around the canvas)

However as soon as I define the selection variable, the position of the object completely changes, without changing position visually. Most top and left attributes become negative, I found out that their new position represent their distance from the center of the group of objects.

This causes persistent effects on the canvas, when I call selection.addWithUpdate() the bounding box appears in the same place, but the object controls (resize and rotation dots) are still on the incorrect position. I tried using selection.setCoords() to reset the controls, but it had no effect.

When I loop through every object and console.log the obj.left and obj.top I get the mostly negative values, as previously mentioned, i.e. the position of the object controls.

var selection = new fabric.ActiveSelection(canvas.getObjects(), { canvas: canvas });
selection.scaleToHeight(0.8)
selection.center();

canvas.renderAll()
selection.addWithUpdate()
selection.setCoords()

enter image description here

2 Answers

The reason why the coordinates go into the negative is that the selection thinks (0, 0) is the center of the selection. You have probably seen values like this on your objects:

enter image description here

Adding the left and top attributes of the selection itself to the object calculates to the original position. Something simple like this is all you need:

function calculateOriginalPosition(selection) {
  selectionObjects = selection.getObjects();

  selectionObjects.forEach((object) => {
    // Giving each object the original position.
    object.left += selection.left;
    object.top += selection.top;

    // Do something with your object here
  });
}
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
    <meta http-equiv="cleartype" content="on">

    <link rel="stylesheet" href="style.css">
    <script src="qwery-bonzo-bean.js"></script>
    <script src="qbb-config.js"></script>
    <script src="fabric-1.3.0.js"></script>
    <script src="script.js"></script>
</head>

<body onload="init();">
    <div id="toolbar">
        <button id="mobilePortrait" data-scale="320px,480px">320x480</button>
        <button id="mobileLandscape" data-scale="480px,320px">480x320</button>
  
        <button id="tabletPortrait" data-scale="768px,1024px">768x1024</button>
        <button id="tabletLandscape" data-scale="1024px,768px">1024x768</button>
  
        <button id="fullscreen" data-scale="100%,100%">100%</button>
    </div>
    <div id="viewport">
        <div id="content">
        <div id="map">
            <div id="bg" class="scalable"><img src="http://img.wallpaperstock.net:81/building-and-sky-wallpapers_575_1024x768.jpg" /></div>
            </div>
            <div id="canvi">
                <canvas id="draw_canvas" width="1024" height="768"></canvas>
            </div>
        </div>
    </div>
    <div id="viewportBorder"></div>
    </body>

</html>
Related