fabric.js 3.6 - 更改分组对象时分组的边界框不更新
fabric.js 3.6 - Bounding box for group doesn't update when grouped objects are changed
我遇到的 fabric.js 的问题看起来很简单,但我一直在寻找解决方案,但没有任何运气,所以我来了。
我创建了一个简单的组来绘制一个箭头,由一个线对象和一个放置在其端点的旋转三角形组成。这工作正常,但是当我动态更新线条的笔划宽度和三角形的 width/height 时,组的边界框不会更新以匹配新尺寸。这是结果的图片:
这是一个现场演示。只需拖动滑块来更改描边宽度和三角形大小,您就会看到问题。
let canvas = new fabric.Canvas(document.querySelector('canvas'), {
backgroundColor: 'white'
}),
object,
lineCoords = [100, 75, 250, 75],
strokeWidth = parseFloat(document.querySelector('.strokewidth').value),
createArrow = () => {
return new fabric.Group(
[
new fabric.Line(lineCoords, {
left: lineCoords[0],
top: lineCoords[1],
stroke: 'red',
strokeWidth: strokeWidth,
strokeLineCap: "round",
}),
new fabric.Triangle({
width: strokeWidth + 22,
height: strokeWidth + 22,
fill: 'red',
left: lineCoords[0] + 150 + strokeWidth + 22 + ((strokeWidth + 22) / 2) - 14,
top: lineCoords[1] - (Math.floor((strokeWidth + 22) / 2)) + (Math.floor(strokeWidth / 2)),
angle: 90,
})
],
{ objectCaching: false }
)
}
let arrow = createArrow()
canvas.add(arrow)
canvas.setActiveObject(arrow)
canvas.renderAll()
$('body').on('input change', '.strokewidth', e => {
if (object = canvas.getActiveObject()) {
let value = parseFloat(e.target.value),
[ line, triangle ] = object.getObjects()
line.set({
strokeWidth: value
})
triangle.set({
width: value + 22,
height: value + 22,
left: line.left + line.width + value + 22 + ((value + 22) / 2) - 14,
top: line.top - (Math.floor((value + 22) / 2)) + (Math.floor(value / 2))
})
canvas.renderAll()
}
})
body {
background: #f0f0f0;
padding: 0;
margin: 0;
}
canvas {
border: 1px solid lightgray;
}
div {
margin: 0.5em 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="400" height="150"></canvas>
<div>
<input type="range" class="strokewidth" min="1" max="40" value="5">
</div>
我使用的是 fabric.js 的 3.6 版。显然有一种方法可以刷新旧版本中的边界框,但是 none 代码适用于 3.6 - 这些功能不再存在。我已经尝试了几种方法来修复它,包括取消组合和重新组合对象,但到目前为止没有任何运气。
有谁知道在这种情况下如何强制重新计算边界框?感谢您的帮助。
在 FabricJS 3 中,缩放一组对象的最佳方法是更改整个组的 scale
值:
group.set({ scaleX: value, scaleY: value })
我假设有时只需要缩放组内的某些对象或以不同的比例缩放它们。我认为从历史上看,这种繁重的操作需要由开发人员触发。有一种方法可以做到这一点 addWithUpdate 并且可以在不向其传递对象的情况下调用它。
let canvas = new fabric.Canvas(document.querySelector('canvas'), {
backgroundColor: 'white'
}),
object,
lineCoords = [100, 75, 250, 75],
strokeWidth = parseFloat(document.querySelector('.strokewidth').value),
createArrow = () => {
return new fabric.Group(
[
new fabric.Line(lineCoords, {
left: lineCoords[0],
top: lineCoords[1],
stroke: 'red',
strokeWidth: strokeWidth,
strokeLineCap: "round",
}),
new fabric.Triangle({
width: strokeWidth + 22,
height: strokeWidth + 22,
fill: 'red',
left: lineCoords[0] + 150 + strokeWidth + 22 + ((strokeWidth + 22) / 2) - 14,
top: lineCoords[1] - (Math.floor((strokeWidth + 22) / 2)) + (Math.floor(strokeWidth / 2)),
angle: 90,
})
],
{ objectCaching: false }
)
}
let arrow = createArrow()
canvas.add(arrow)
canvas.setActiveObject(arrow)
canvas.renderAll()
$('body').on('input change', '.strokewidth', e => {
if (object = canvas.getActiveObject()) {
let value = parseFloat(e.target.value),
[ line, triangle ] = object.getObjects()
line.set({
strokeWidth: value
})
triangle.set({
width: value + 22,
height: value + 22,
left: line.left + line.width + value + 22 + ((value + 22) / 2) - 14,
top: line.top - (Math.floor((value + 22) / 2)) + (Math.floor(value / 2))
})
canvas.renderAll()
arrow.addWithUpdate()
}
})
body {
background: #f0f0f0;
padding: 0;
margin: 0;
}
canvas {
border: 1px solid lightgray;
}
div {
margin: 0.5em 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="400" height="150"></canvas>
<div>
<input type="range" class="strokewidth" min="1" max="40" value="5">
</div>
我遇到的 fabric.js 的问题看起来很简单,但我一直在寻找解决方案,但没有任何运气,所以我来了。
我创建了一个简单的组来绘制一个箭头,由一个线对象和一个放置在其端点的旋转三角形组成。这工作正常,但是当我动态更新线条的笔划宽度和三角形的 width/height 时,组的边界框不会更新以匹配新尺寸。这是结果的图片:
这是一个现场演示。只需拖动滑块来更改描边宽度和三角形大小,您就会看到问题。
let canvas = new fabric.Canvas(document.querySelector('canvas'), {
backgroundColor: 'white'
}),
object,
lineCoords = [100, 75, 250, 75],
strokeWidth = parseFloat(document.querySelector('.strokewidth').value),
createArrow = () => {
return new fabric.Group(
[
new fabric.Line(lineCoords, {
left: lineCoords[0],
top: lineCoords[1],
stroke: 'red',
strokeWidth: strokeWidth,
strokeLineCap: "round",
}),
new fabric.Triangle({
width: strokeWidth + 22,
height: strokeWidth + 22,
fill: 'red',
left: lineCoords[0] + 150 + strokeWidth + 22 + ((strokeWidth + 22) / 2) - 14,
top: lineCoords[1] - (Math.floor((strokeWidth + 22) / 2)) + (Math.floor(strokeWidth / 2)),
angle: 90,
})
],
{ objectCaching: false }
)
}
let arrow = createArrow()
canvas.add(arrow)
canvas.setActiveObject(arrow)
canvas.renderAll()
$('body').on('input change', '.strokewidth', e => {
if (object = canvas.getActiveObject()) {
let value = parseFloat(e.target.value),
[ line, triangle ] = object.getObjects()
line.set({
strokeWidth: value
})
triangle.set({
width: value + 22,
height: value + 22,
left: line.left + line.width + value + 22 + ((value + 22) / 2) - 14,
top: line.top - (Math.floor((value + 22) / 2)) + (Math.floor(value / 2))
})
canvas.renderAll()
}
})
body {
background: #f0f0f0;
padding: 0;
margin: 0;
}
canvas {
border: 1px solid lightgray;
}
div {
margin: 0.5em 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="400" height="150"></canvas>
<div>
<input type="range" class="strokewidth" min="1" max="40" value="5">
</div>
我使用的是 fabric.js 的 3.6 版。显然有一种方法可以刷新旧版本中的边界框,但是 none 代码适用于 3.6 - 这些功能不再存在。我已经尝试了几种方法来修复它,包括取消组合和重新组合对象,但到目前为止没有任何运气。
有谁知道在这种情况下如何强制重新计算边界框?感谢您的帮助。
在 FabricJS 3 中,缩放一组对象的最佳方法是更改整个组的 scale
值:
group.set({ scaleX: value, scaleY: value })
我假设有时只需要缩放组内的某些对象或以不同的比例缩放它们。我认为从历史上看,这种繁重的操作需要由开发人员触发。有一种方法可以做到这一点 addWithUpdate 并且可以在不向其传递对象的情况下调用它。
let canvas = new fabric.Canvas(document.querySelector('canvas'), {
backgroundColor: 'white'
}),
object,
lineCoords = [100, 75, 250, 75],
strokeWidth = parseFloat(document.querySelector('.strokewidth').value),
createArrow = () => {
return new fabric.Group(
[
new fabric.Line(lineCoords, {
left: lineCoords[0],
top: lineCoords[1],
stroke: 'red',
strokeWidth: strokeWidth,
strokeLineCap: "round",
}),
new fabric.Triangle({
width: strokeWidth + 22,
height: strokeWidth + 22,
fill: 'red',
left: lineCoords[0] + 150 + strokeWidth + 22 + ((strokeWidth + 22) / 2) - 14,
top: lineCoords[1] - (Math.floor((strokeWidth + 22) / 2)) + (Math.floor(strokeWidth / 2)),
angle: 90,
})
],
{ objectCaching: false }
)
}
let arrow = createArrow()
canvas.add(arrow)
canvas.setActiveObject(arrow)
canvas.renderAll()
$('body').on('input change', '.strokewidth', e => {
if (object = canvas.getActiveObject()) {
let value = parseFloat(e.target.value),
[ line, triangle ] = object.getObjects()
line.set({
strokeWidth: value
})
triangle.set({
width: value + 22,
height: value + 22,
left: line.left + line.width + value + 22 + ((value + 22) / 2) - 14,
top: line.top - (Math.floor((value + 22) / 2)) + (Math.floor(value / 2))
})
canvas.renderAll()
arrow.addWithUpdate()
}
})
body {
background: #f0f0f0;
padding: 0;
margin: 0;
}
canvas {
border: 1px solid lightgray;
}
div {
margin: 0.5em 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="400" height="150"></canvas>
<div>
<input type="range" class="strokewidth" min="1" max="40" value="5">
</div>