我有两个 Canvas 层,彼此堆叠。顶层名为top
,底层名为bottom
。在顶层
上,我添加了一些透明
的对象,并且只显示它们的句柄。 bottom
层应该克隆
来自top
的对象,更改一些属性并绘制它们。
只要我只移动顶层
上的单个对象,这种方法就可以正常工作。当我选择一组对象并开始移动整个组时,出现了一些问题。在top
层上一切正常,但bottom
层上的对象被绘制到 Canvas 的左上角。仅当我开始再次拖动单个对象时,此问题才会得到纠正。
我希望有人可以看一下并可能知道出了什么问题:)
var top = new fabric.Canvas("top", {renderOnAddRemove:false});
var bottom = new fabric.Canvas("bottom", {renderOnAddRemove:false});
var update = function () {
bottom.clear().add.apply(bottom, top.getObjects().map(function (o) {
return o.clone().set({
selectable: false,
hasBorders: false,
hasControls: false,
fill: "rgba(255,0,0,.5)",
globalCompositeOperation: "xor"
});
})).renderAll();
};
top.on({
"object:modified": update
});
最佳答案
结构中的组很棘手,因为所有变换('top'、'left'、'scaleX'、'scaleY')都相对于父组的位置,而父组的位置都相对于组的中心。因此,当您想要提取顶级 Canvas 位置时,您需要做一些工作来从组中获取变换并将其应用到对象。在结构内部,当您对内容进行分组和取消分组时,就会发生这种情况。
在此示例中,我使所有对象具有与组的默认原点(中心)相同的 X 和 Y 原点。这使得矩阵计算匹配。如果您想保留形状的默认顶部/左侧原点,则需要进行额外的数学计算来计算正确的位置。
var topCanvas = new fabric.Canvas("top", {renderOnAddRemove:false});
var bottomCanvas = new fabric.Canvas("bottom", {renderOnAddRemove:false});
fabric.Object.prototype.originX = 'center';
fabric.Object.prototype.originY = 'center';
var update = function () {
bottomCanvas.clear().add.apply(bottomCanvas, topCanvas.getObjects().map(function (o) {
var clone = o.clone();
clone.set({
selectable: false,
hasBorders: false,
hasControls: false,
fill: "rgba(255,0,0,.5)",
globalCompositeOperation: "xor",
});
if (o.group) {
var matrix = o.calcTransformMatrix();
var transforms = fabric.util.qrDecompose(matrix);
clone.set({
angle: transforms.angle,
skewX: transforms.skewX,
skewY: transforms.skewY,
scaleX: transforms.scaleX,
scaleY: transforms.scaleY,
top: transforms.translateY,
left: transforms.translateX,
});
}
return clone;
})).renderAll();
};
topCanvas.on({
"object:modified": update
});
topCanvas
.add(new fabric.Rect({
top: 50,
left: 50,
width: 100,
height: 100,
fill: "transparent"
}))
.add(new fabric.Rect({
top: 100,
left: 100,
width: 100,
height: 100,
fill: "transparent"
}))
.add(new fabric.Rect({
top: 150,
left: 150,
width: 100,
height: 100,
fill: "transparent"
}))
.renderAll();
update();
#cont {
position: relative;
width: 400px;
height: 300px;
border: 1px solid;
}
canvas, .canvas-container {
position: absolute!important;
left: 0!important;
top: 0!important;
width: 100%!important;
height: 100%!important;
}
<div id="cont">
<canvas id="bottom" width="400" height="300"></canvas>
<canvas id="top" width="400" height="300"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script>
关于javascript - FabricJS - 选择多个对象时将对象克隆到另一个 Canvas 会出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39119913/