Решение основано на разгруппировке группы объектов при сохранении их состояния, добавлении опции subTargetCheck:true
в качестве true
к fabric.Group
объектам, содержащим текст, который вы хотите отредактировать.
разгруппировка достигается на имитируемом событии двойного щелчка с использованием прослушивателя mousedown
в группе объектов верхнего уровня.Слушатель mousedown
также добавляется к текстовым объектам в группе.
После редактирования текста объекты перегруппируются, удаляя исходные объекты и заменяя их новой группой с такими же свойствами в 'редактирование: выход 'событие, возвращаемое fabric.js
.
const canvas = new fabric.Canvas("canvas");
canvas.setWidth(350);
canvas.setHeight(350);
// Double-click event handler
const fabricDblClick = function(obj, handler) {
return function() {
if (obj.clicked) handler(obj);
else {
obj.clicked = true;
setTimeout(function() {
obj.clicked = false;
}, 500);
}
};
};
// ungroup objects in group
let groupItems = [];
let ungroup = function(group) {
groupItems = group._objects;
group._restoreObjectsState();
canvas.remove(group);
for (var i = 0; i < groupItems.length; i++) {
canvas.add(groupItems[i]);
}
canvas.renderAll();
};
// Re-group when text editing finishes
const firstText = new fabric.IText("First Text", {
fontFamily: "Comic Sans",
fontSize: 14,
stroke: "#000",
strokeWidth: 1,
fill: "#000",
left: 170,
top: 60
});
const secondText = new fabric.IText("Second Text", {
fontFamily: "Comic Sans",
fontSize: 14,
stroke: "#000",
strokeWidth: 1,
fill: "#000",
left: 170,
top: 80
});
firstText.on("editing:exited", () => {
var items = [];
groupItems.forEach(function(obj) {
items.push(obj);
canvas.remove(obj);
});
const newTextGroup = new fabric.Group(items.reverse(), {
subTargetCheck: true
});
canvas.add(newTextGroup);
newTextGroup.on(
"mousedown",
fabricDblClick(newTextGroup, obj => {
ungroup(newTextGroup);
})
);
});
let addGroup = () => {
const textGroup = new fabric.Group([secondText, firstText], {
left: 50,
top: 50,
subTargetCheck: true
});
canvas.add(textGroup);
textGroup.on(
"mousedown",
fabricDblClick(textGroup, obj => {
if (isTextGroup(obj)) {
obj.getObjects().forEach(item => {
item.on("mousedown", e => {
if (e.target.type === "i-text") {
e.target.enterEditing();
e.target.hiddenTextarea.focus();
}
});
});
}
ungroup(textGroup);
})
);
};
addGroup();
let isTextGroup = object => {
return object.getObjects().every(el => {
return el.type === "i-text";
});
};
.canvas {
width: 350px;
height: 350px;
border: 1px solid Black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.6.0/fabric.min.js"></script>
<canvas id="canvas" class="canvas" ></canvas>