我有一个从SVG标签加载的Fabric组。 SVG内容更改时,我想相应地更改Fabric组。 可悲的是,如果我只是从Fabric组中删除所有内容并回推SVG内容,它将重置组的位置,缩放和转换。
我在那里有什么选择?
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<script src="https://cdn.jsdelivr.net/jsbarcode/3.6.0/JsBarcode.all.min.js"></script>
<button id="change">Change barcode</button>
<div id="divBarcode">
<svg id="svgBarcode"></svg>
</div>
<canvas id="fabric" width="500px" height="500px" style="border: 1px solid #000;">
<script>
let canvas = new fabric.Canvas("fabric");
let barcode = undefined;
// Creates a barcode
JsBarcode("#svgBarcode", "Example 1234", {
background: null,
format: "CODE128"
});
// Removes the font style because fabric has parse errors
$("#svgBarcode text").attr("style", "");
// Adds the barcode in fabric
fabric.loadSVGFromString($("#divBarcode").html(), (objects, options) => {
barcode = new fabric.util.groupSVGElements(objects, options);
canvas.add(barcode);
canvas.requestRenderAll();
});
$("#change").click(e => {
// We generate a new svg barcode
JsBarcode("#svgBarcode", "New one", {
background: null,
format: "CODE128"
});
$("#svgBarcode text").attr("style", "");
// Now here is the tricky part, I need to change it in fabric too
fabric.loadSVGFromString($("#divBarcode").html(), (objects, options) => {
barcode.getObjects().forEach(obj => barcode.remove(obj));
objects.forEach(obj => barcode.addWithUpdate(obj));
canvas.requestRenderAll();
// But it resets the position and scaling
});
});
</script>
答案 0 :(得分:1)
您需要这样的想法吗?
let canvas = new fabric.Canvas("fabric");
let barcode = undefined;
// Creates a barcode
JsBarcode("#svgBarcode", "Example 1234", {
background: null,
format: "CODE128"
});
// Removes the font style because fabric has parse errors
$("#svgBarcode text").attr("style", "");
// Adds the barcode in fabric
fabric.loadSVGFromString($("#divBarcode").html(), (objects, options) => {
barcode = new fabric.util.groupSVGElements(objects, options);
canvas.add(barcode);
canvas.requestRenderAll();
});
$("#change").click(e => {
// We generate a new svg barcode
JsBarcode("#svgBarcode", "New one", {
background: null,
format: "CODE128"
});
$("#svgBarcode text").attr("style", "");
var originalTransfomation = {
left:canvas.getObjects()[0].left,
top:canvas.getObjects()[0].top,
width:canvas.getObjects()[0].width,
height:canvas.getObjects()[0].height,
skewY:canvas.getObjects()[0].skewY,
skewX:canvas.getObjects()[0].skewX,
scaleX:canvas.getObjects()[0].scaleX,
scaleY:canvas.getObjects()[0].scaleY,
angle:canvas.getObjects()[0].angle
}
// Now here is the tricky part, I need to change it in fabric too
fabric.loadSVGFromString($("#divBarcode").html(), (objects, options) => {
barcode.getObjects().forEach(obj => barcode.remove(obj));
objects.forEach(obj => barcode.addWithUpdate(obj));
barcode.left = originalTransfomation.left;
barcode.top = originalTransfomation.top;
barcode.width = originalTransfomation.width;
barcode.height = originalTransfomation.height;
barcode.scaleY = originalTransfomation.scaleY;
barcode.scaleX = originalTransfomation.scaleX;
barcode.angle = originalTransfomation.angle;
barcode.skewX= originalTransfomation.skewX;
barcode.skewY= originalTransfomation.skewY;
barcode.setCoords();
canvas.requestRenderAll();
// But it resets the position and scaling
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<script src="https://cdn.jsdelivr.net/jsbarcode/3.6.0/JsBarcode.all.min.js"></script>
<button id="change">Change barcode</button>
<div id="divBarcode">
<svg id="svgBarcode"></svg>
</div>
<canvas id="fabric" width="500px" height="500px" style="border: 1px solid #000;">