Snapping of objects

by 20yco

HTML

<canvas id="c" width="800" height="500" style="border:1px solid #ccc"></canvas>

JavaScript

var canvas = new fabric.Canvas('canvas');

fabric.RectWithRect = fabric.util.createClass(fabric.Rect, {
          type: 'f_paragraph',
          text: undefined,
          textOffsetLeft: 0,
          textOffsetTop: 0,
          _prevObjectStacking: null,
          _prevAngle: 0,
          minWidth: 50,
          minHeight: 50,   

          _currentScaleFactorX: 1,
          _currentScaleFactorY: 1,

          _lastLeft: 0,
          _lastTop: 0,

          recalcTextPosition: function () {
               //this.insideRect.setCoords();
               const sin = Math.sin(fabric.util.degreesToRadians(this.angle))
               const cos = Math.cos(fabric.util.degreesToRadians(this.angle))
               const newTop = sin * this.insideRectOffsetLeft + cos * this.insideRectOffsetTop
               const newLeft = cos * this.insideRectOffsetLeft - sin * this.insideRectOffsetTop
               const rectLeftTop = this.getPointByOrigin('left', 'top')
               this.insideRect.set('left', rectLeftTop.x + newLeft)
               this.insideRect.set('top', rectLeftTop.y + newTop)
               this.insideRect.set('width', this.width - 40)
               this.insideRect.set('height', this.height - 40)
               this.insideRect.set('scaleX', this.scaleX)
               this.insideRect.set('scaleY', this.scaleY)
          },
         
         initialize: function (textOptions, rectOptions) {
           this.callSuper('initialize', rectOptions)

           this.insideRect = new fabric.Rect({
             ...textOptions,
             dirty: false,
             objectCaching: false,
             selectable: false,
             evented: false,
             fragmentType: 'rectWidthRect'
           });
           canvas.bringToFront(this.insideRect);
           this.insideRect.width = this.width - 40;
           this.insideRect.height = this.height - 40;
           this.insideRect.left = this.left + 20;
           this.insideRect.top = this.top + 20;
          ...