Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to apply back and forth scalling to all objects in fabricJS?

I have multiple canvas in one screen using fabricJS.

I have added some ITexts, Text Box, Image, Background in each canvas.

I have some scalling options, like 25%, 50%, 100% to 300% in increasing order of 25%.

If my current default scale is 100% it means scalefactor is 1, now if I apply 125 or 150 or whatever then it is working fine with this code. but once I go down means 25 or 50 then again 150 or 175. then it starts to behave strange. my code is here. I tried to do scaling based on initial scalefactor but its not working as expected.

        const scalefactor = Number(this.selectedScale) / 100;
        this.canvas.forEach((canvas: any, index) => {

            this.canvas[index].setDimensions({
                width: Number(this.canvas[index].originalCanvasWidth * scalefactor),
                height: Number(this.canvas[index].originalCanvasHeight * scalefactor)
            });

            this.canvas[index].setZoom(scalefactor);


            if (this.canvas[index].backgroundImage) {
                // Need to scale background images as well
                let bi = this.canvas[index];
                bi.width = bi.originalBackgroundImageWidth * scalefactor;
                bi.height = bi.originalBackgroundImageHeight * scalefactor;
            }

            let objects = this.canvas[index].getObjects();
            for (let i in objects) {
                const scaleX = objects[i].scaleX;
                const scaleY = objects[i].scaleY;
                const left = objects[i].left;
                const top = objects[i].top;

                const tempScaleX = scaleX * scalefactor;
                const tempScaleY = scaleY * scalefactor;
                const tempLeft = left * scalefactor;
                const tempTop = top * scalefactor;

                objects[i].scaleX = tempScaleX;
                objects[i].scaleY = tempScaleY;
                objects[i].left = tempLeft;
                objects[i].top = tempTop;

                objects[i].setCoords();
            }

            this.canvas[index].renderAll();
            this.canvas[index].calcOffset();
        });

for canvas and background its working fine only for objects its not scalling properly as well as its position is not setting properly.

like image 321
Dr. Piyush Dholariya Avatar asked Jun 24 '19 08:06

Dr. Piyush Dholariya


1 Answers

keep in mind that you need to use the old scale. Example. you have a canvas of 100px...you scale down to 0.5 (that means 50 px) and after this you apply a scale of 1.5.. the result result should be 150px but instead is 75 because you multiply the scaled canvas.

    const scalefactor = Number(this.selectedScale) / 100;
  const oldScaleFactor = Number(this.oldScaleFactor) / 100;  //this.oldScaleFactor should be 100 at the first time
        this.canvas.forEach((canvas: any, index) => {

            this.canvas[index].setDimensions({
                width: Number(this.canvas[index].originalCanvasWidth / oldScaleFactor * scalefactor),
                height: Number(this.canvas[index].originalCanvasHeight / oldScaleFactor * scalefactor)
            });

            this.canvas[index].setZoom(scalefactor);


            if (this.canvas[index].backgroundImage) {
                // Need to scale background images as well
                let bi = this.canvas[index];
                bi.width = bi.originalBackgroundImageWidth / oldScaleFactor * scalefactor;
                bi.height = bi.originalBackgroundImageHeight / oldScaleFactor * scalefactor;
            }

            let objects = this.canvas[index].getObjects();
            for (let i in objects) {
                const scaleX = objects[i].scaleX;
                const scaleY = objects[i].scaleY;
                const left = objects[i].left;
                const top = objects[i].top;

                const tempScaleX = scaleX / oldScaleFactor * scalefactor;
                const tempScaleY = scaleY / oldScaleFactor * scalefactor;
                const tempLeft = left / oldScaleFactor * scalefactor;
                const tempTop = top  / oldScaleFactor * scalefactor;

                objects[i].scaleX = tempScaleX;
                objects[i].scaleY = tempScaleY;
                objects[i].left = tempLeft;
                objects[i].top = tempTop;

                objects[i].setCoords();
            }

            this.canvas[index].renderAll();
            this.canvas[index].calcOffset();
        });
like image 62
Marius Turcu Avatar answered Oct 31 '22 21:10

Marius Turcu