Fabric.js 边界框与线对齐

问题描述 投票:0回答:1

在 Fabric.js 中,垂直线的边界框与线本身一样小。 当线不是垂直或水平时,边界框会占用更多表面。

我希望边界框始终沿着线,即使线不是垂直或水平的。 是否有选项或方法可以重新生成具有特定角度(线的相同角度)的边界框?

fabricjs
1个回答
0
投票

旋转的水平线或垂直线沿线有边界框。您可以利用它来解决这个问题。所以,我通过重新画线解决了这个问题。绘制水平线,然后旋转它。给定

originalLine
,计算
angle
length
。然后用
angle
length
重新画线。让我们调用重新绘制的线
newLine

let canvas = new fabric.Canvas('canvas', {
    selection: true
});
const startX = 20;
const startY = 20;
const size = 20;

const originalLine = new fabric.Line([startX, startY, 100, 100], {
    stroke: 'red',
    strokeWidth: size,
    originX: 'center',
    originY: 'center',
});

// Calculate angle and length for the new line
const dx = originalLine.x2 - originalLine.x1;
const dy = originalLine.y2 - originalLine.y1;
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
const length = Math.sqrt(dx * dx + dy * dy);

// create a new horizontal line, then rotate it
const newLine = new fabric.Line([startX, startY, startX + length, startY], {
    stroke: 'blue',
    strokeWidth: size,
    angle: angle,
    originX: 'left',
    originY: 'center',
});

canvas.add(newLine);
canvas.setActiveObject(newLine);
canvas.renderAll();
canvas {
    border: 1px solid #000;
}
<head>
  <link rel="stylesheet" href="styles.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
</head>

<body>
  <canvas id="canvas" width="200" height="200"></canvas>
  <script src="script.js"></script>
</body>

originX
originY
originalLine
都很重要。否则,新创建的行将移动一点。下面进一步解释其原因。
这可能存在一个问题。新创建的线原点位于左中,您可能更喜欢默认原点左上角。在这种情况下,您可以更新 origin,然后更新 

newLine

top

left
let canvas = new fabric.Canvas('canvas', {
    selection: true
});
const startX = 20;
const startY = 20;
const size = 20;

const originalLine = new fabric.Line([startX, startY, 100, 100], {
    stroke: 'red',
    strokeWidth: size,
    originX: 'center',
    originY: 'center',
});

// Calculate angle and length for the new line
const dx = originalLine.x2 - originalLine.x1;
const dy = originalLine.y2 - originalLine.y1;
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
const length = Math.sqrt(dx * dx + dy * dy);

// create a new horizontal line, then rotate it
const newLine = new fabric.Line([startX, startY, startX + length, startY], {
    stroke: 'blue',
    strokeWidth: size,
    angle: angle,
    originX: 'left',
    originY: 'center',
});
// this make `tl` available
newLine.setCoords();
canvas.add(newLine);

// tl have correct values for `top` and `left`
const correct_top = newLine.lineCoords.tl.y;
const correct_left = newLine.lineCoords.tl.x;
newLine.set({
    originY: 'top',
    top: correct_top,
    left: correct_left,
})

canvas.setActiveObject(newLine);
canvas.renderAll();
canvas {
    border: 1px solid #000;
}

更多关于起源

首先,请参考此原始可视化。

http://fabricjs.com/test/misc/origin.html

如果您在早期代码中忽略了

<head> <link rel="stylesheet" href="styles.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script> </head> <body> <canvas id="canvas" width="200" height="200"></canvas> <script src="script.js"></script> </body>

originX
,则新行将移动一点。在下面的画布中,红色是
originY
,蓝色是重新绘制的线
originalLine
。圆圈用于可视化起点。您可以看到两条线之间有一个小的移位/间隙,即使它们绘制在相同的起始位置。

newLine
let canvas = new fabric.Canvas('canvas', {
    selection: true
});
const startX = 20;
const startY = 20;
const size = 20;

const originalLine = new fabric.Line([startX, startY, 100, 100], {
    stroke: 'red',
    strokeWidth: size,
});

// Calculate angle and length for the new line
const dx = originalLine.x2 - originalLine.x1;
const dy = originalLine.y2 - originalLine.y1;
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
const length = Math.sqrt(dx * dx + dy * dy);

// create a new horizontal line, then rotate it
const newLine = new fabric.Line([startX, startY, startX + length, startY], {
    stroke: 'blue',
    strokeWidth: size,
    angle: angle,
});

// visualize starting point
const startPoint = new fabric.Circle({
    left: startX,
    top: startY,
    radius: 5,
    fill: 'green',
    originX: 'center',
    originY: 'center',
    selectable: false
});

canvas.add(newLine);
canvas.add(originalLine);
canvas.add(startPoint);
canvas.setActiveObject(originalLine);
canvas.renderAll();
canvas {
    border: 1px solid #000;
}

移动的原因是因为正如您在上面的画布中看到的,对于

<head> <link rel="stylesheet" href="styles.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script> </head> <body> <canvas id="canvas" width="200" height="200"></canvas> <script src="script.js"></script> </body>

,起点和线的左端之间存在一些间隙。

originalLine
越大,这个问题就越明显。因此,即使
strokeWidth
绘制在相同的起始位置,也会存在一些移位/间隙。
这就是为什么 

newLine

需要

originX
center
originY
center
originalLine
originX
left
originY
center
newLine
是需要的。使用这些原始值,
originalLine
newLine
之间不会有偏移/间隙。

© www.soinside.com 2019 - 2024. All rights reserved.