[英]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.