Fabricjs: редактирование текста в группе - PullRequest
0 голосов
/ 23 февраля 2019

Fabric.js не поддерживает редактирование текстовых объектов, когда они находятся в группе.Как можно достичь этой функции?

1 Ответ

0 голосов
/ 23 февраля 2019

Решение основано на разгруппировке группы объектов при сохранении их состояния, добавлении опции 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>
...