繁体   English   中英

Fabric js中的对象对齐

[英]object alignment in fabric js

我正在尝试在画布中实现对象对齐(即右、中、左、上、下)。 假设用户选择了一个对象(即文本或图像),那么如果用户点击右对齐选项,那么所选对象应该与右侧对齐。

我尝试了以下两种方法,但没有成功。

 var canvas = new fabric.Canvas('a'); canvas.add(new fabric.Rect({ left: 50, top: 50, height: 50, width: 50, fill: 'red' })); canvas.add(new fabric.Rect({ left: 130, top: 50, height: 50, width: 50, fill: 'green' })); canvas.add(new fabric.Rect({ left: 90, top: 130, height: 50, width: 50, fill: 'blue' })); canvas.renderAll(); $('.alignment').click(function() { var cur_value = $(this).attr('data-action'); if (cur_value != '') { process_align(cur_value); } else { alert('Please select a item'); return false; } }); /* Align the selected object */ function process_align(val) { switch (val) { case 'right': //Tried below one with //activeObj.setPositionByOrigin(new fabric.Point(activeObj.top, canvas.getWidth()), activeObj.originY,'center'); //Tried below one but its not working var activeObj = canvas.getActiveObject(); activeObj.set({ originX: 'right', //originY: 'center' }); activeObj.setCoords(); canvas.renderAll(); break; } }
 canvas { border: 2px solid black; }
 <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script> <button class="alignment" data-action="left">Align Left</button> <button class="alignment" data-action="center">Align Center</button> <button class="alignment" data-action="right">Align Right</button> <button class="alignment" data-action="top">Align Top</button> <button class="alignment" data-action="bottom">Align Bottom</button> <canvas id="a" width="400" height="200"></canvas>

我只实现了右对齐,因为我不确定如何为其他对齐(上、下、左、中)进行对齐。

 var canvas = new fabric.Canvas('a'); canvas.add(new fabric.Rect({ left: 50, top: 50, height: 50, width: 50, fill: 'red' })); canvas.add(new fabric.Rect({ left: 130, top: 50, height: 50, width: 50, fill: 'green' })); canvas.add(new fabric.Rect({ left: 90, top: 130, height: 50, width: 50, fill: 'blue' })); canvas.renderAll(); $('.alignment').click(function() { var cur_value = $(this).attr('data-action'); var activeObj = canvas.getActiveObject() || canvas.getActiveGroup(); if (cur_value != '' && activeObj) { process_align(cur_value, activeObj); activeObj.setCoords(); canvas.renderAll(); } else { alert('Please select a item'); return false; } }); /* Align the selected object */ function process_align(val, activeObj) { switch (val) { case 'left': activeObj.set({ left: 0 }); break; case 'right': activeObj.set({ left: canvas.width - (activeObj.width * activeObj.scaleX) }); break; case 'top': activeObj.set({ top: 0 }); break; case 'bottom': activeObj.set({ top: canvas.height - (activeObj.height * activeObj.scaleY) }); break; case 'center': activeObj.set({ left: (canvas.width / 2) - ((activeObj.width * activeObj.scaleX) / 2) }); break; } }
 canvas { border: 2px solid black; }
 <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script> <button class="alignment" data-action="left">Align Left</button> <button class="alignment" data-action="center">Align Center</button> <button class="alignment" data-action="right">Align Right</button> <button class="alignment" data-action="top">Align Top</button> <button class="alignment" data-action="bottom">Align Bottom</button> <canvas id="a" width="400" height="200"></canvas>

您可以根据需要设置左/上,然后setCoords() 检查片段。

虽然其他答案让我走上了正确的轨道,但它们都没有真正适用于旋转的对象,诀窍是将变换原点设置为中心,并像 DivPusher 指出的那样使用 getBoundingRect() 。

 //Override fabric transform origin to center fabric.Object.prototype.set({ originX:'center', originY:'center', }); var canvas = new fabric.Canvas('a'); canvas.add(new fabric.Rect({ left: 50, top: 50, height: 50, width: 50, fill: 'red' })); canvas.add(new fabric.Text('Fabricjs', { left: 200, top: 80, fill: '#555', angle: 35, scaleX: .8, scaleY: .8, })); canvas.add(new fabric.Rect({ left: 90, top: 130, height: 50, width: 50, fill: 'blue', angle: 45, })); canvas.renderAll(); $('.alignment').click(function() { var cur_value = $(this).attr('data-action'); var activeObj = canvas.getActiveObject() || canvas.getActiveGroup(); if (cur_value != '' && activeObj) { process_align(cur_value, activeObj); activeObj.setCoords(); canvas.renderAll(); } else { alert('Please select an item'); return false; } }); /* Align the selected object */ function process_align(val, activeObj) { const bound = activeObj.getBoundingRect() switch (val) { case 'left': activeObj.set({ left: activeObj.left - bound.left }); break; case 'right': activeObj.set({ left: canvas.width - bound.width/2 }); break; case 'top': activeObj.set({ top: activeObj.top - bound.top }); break; case 'bottom': activeObj.set({ top: canvas.height - bound.height/2 }); break; case 'center': activeObj.set({ left: canvas.width / 2 }); break; case 'middle': activeObj.set({ top: canvas.height / 2 }); break; } }
 canvas { border: 2px solid black; }
 <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script> <button class="alignment" data-action="left">Align Left</button> <button class="alignment" data-action="center">Align Center</button> <button class="alignment" data-action="right">Align Right</button> <button class="alignment" data-action="top">Align Top</button> <button class="alignment" data-action="middle">Align Middle</button> <button class="alignment" data-action="bottom">Align Bottom</button> <canvas id="a" width="400" height="200"></canvas>

这是我使用FabricJS 2.0实现的setAlign方法

setAlign(align, canvas) {
    let activeObj = canvas.getActiveObject(),
      horizontalCenter = (activeObj.width * activeObj.scaleX) / 2,
      verticalCenter = (activeObj.height * activeObj.scaleY) / 2,
      { width, height } = canvas

    switch (align) {
      case 'top':
        activeObj.set({ top: verticalCenter })
        break
      case 'left':
        activeObj.set({ left: horizontalCenter })
        break
      case 'bottom':
        activeObj.set({ top: height - verticalCenter })
        break
      case 'right':
        activeObj.set({ left: width - horizontalCenter })
        break
      case 'center':
        activeObj.set({ left: (width / 2) })
        break
      case 'middle':
        activeObj.set({ top: (height / 2) })
        break
    }

    activeObj.setCoords()
    canvas.renderAll()
}

Durga 的答案并不完美,因为如果您顺时针旋转一个框并单击左对齐按钮,则该框将按其左上角对齐,而不是按其实际左边缘对齐。

您需要使用getBoundingRect()函数。 演示:

 var canvas = this.__canvas = new fabric.Canvas('c'); fabric.Object.prototype.transparentCorners = false; var rect = new fabric.Rect({ left: 100, top: 50, width: 100, height: 100, fill: 'green', angle: 20, padding: 0 }); canvas.add(rect); canvas.setActiveObject(canvas.item(0)); canvas.forEachObject(function(obj) { var setCoords = obj.setCoords.bind(obj); obj.on({ moving: setCoords, scaling: setCoords, rotating: setCoords }); }); canvas.on('after:render', function() { canvas.contextContainer.strokeStyle = 'red'; canvas.forEachObject(function(obj) { var bound = obj.getBoundingRect(); canvas.contextContainer.strokeRect( bound.left + 0.5, bound.top + 0.5, bound.width, bound.height ); }) }); function alignLeft(){ var obj = canvas.getActiveObject(); var bound = obj.getBoundingRect(); // console.log(bound.left); // console.log(obj.left); obj.set('left', (obj.left - bound.left)); canvas.getActiveObject().setCoords(); canvas.renderAll(); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.3/fabric.min.js"></script> <button onclick="alignLeft()">align real left</button> <canvas id="c" width="500" height="300" style="border: 1px solid rgb(204, 204, 204); position: absolute; left: 0px; top: 0px; touch-action: none; user-select: none;" ></canvas>

下面的代码可以帮助我在fabric js中的对象组内实现对齐。希望对您有所帮助:

...

var activeObject = this.canvas.getActiveObject();
if (activeObject) {
  var groupWidth = activeObject.getBoundingRect().width;
  var groupHeight = activeObject.getBoundingRect().height;


  this.canvas.getActiveObjects().map((obj: any) => {
    var itemWidth = obj.getBoundingRect().width;
    var itemHeight = obj.getBoundingRect().height;
   
    switch (alignType) {
      case 'left':
        obj.set({
          left: -(groupWidth / 2),
          originX: 'left'
        });
        obj.setCoords();
        this.canvas.renderAll();
        break;
      case 'center':
        obj.set({
          left: (0 - itemWidth / 2),
          originX: 'left'
        });
        obj.setCoords();
        this.canvas.renderAll();

        break;
      case 'right':
        obj.set({
          left: (groupWidth / 2 - itemWidth / 2),
          originX: 'center'
        });
        obj.setCoords();
        this.canvas.renderAll();
        break;
        case 'top':
          if(groupHeight != itemHeight){
            obj.set({
              top:-groupHeight/2
              
            });
            obj.setCoords();
            this.canvas.renderAll();
          }
          break;
          case 'bottom':
          if(groupHeight != itemHeight){
            obj.set({
              
              top: groupHeight / 2 - itemHeight 
              
            
            });
            obj.setCoords();
            this.canvas.renderAll();
          }
          break;
      default:
        break;
    }
  });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM