簡體   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