我正在尝试在画布中实现对象对齐(即右,中,左,上,下)。假设用户选择了一个对象(即文本或图像),然后如果用户点击右对齐选项,则所选对象应该对齐到右侧。
我尝试了以下两种方法但没有成功。
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>
&#13;
我只实现了右对齐,因为我不确定如何对其他对齐(顶部,底部,左侧,中央)进行对齐。
答案 0 :(得分:4)
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();
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;
}
}
&#13;
canvas {
border: 2px solid black;
}
&#13;
<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>
&#13;
您可以根据需要设置左/上,然后setCoords()
。检查代码段。
答案 1 :(得分:1)
Durga的答案并不完美,因为如果顺时针旋转一个框并单击向左对齐按钮,则该框将按其左上角而不是其实际左边缘对齐。 / p>
您需要使用 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>
答案 2 :(得分:1)
虽然其他答案使我走上了正确的轨道,但它们都不是真正适用于旋转对象的方法,但诀窍是将转换原点设置为居中并与DivBusher指出的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('I love 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 a 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>
答案 3 :(得分:0)
这是我使用 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()
}