如何在FabricJS上复制/粘贴后保持IText的可编辑性?

时间:2017-03-21 11:10:24

标签: javascript canvas fabricjs

我想使用FabricJS复制/粘贴对象,问题是当我复制并粘贴一个I文本时,它变得无法编辑,我想使其可编辑。

这里是JsFiddle:http://jsfiddle.net/7Hsdh/11/

Javascript:

var canvas = new fabric.Canvas('paper');

// adding text on canvas
var text = new fabric.Text('Normal Uneditable Text', { 
  left: 100, 
  top: 150,
  fontFamily: 'Arial',
  fontSize: 15,
  fill: '#333'
});
canvas.add(text);

var text = new fabric.IText('IText : not editable anymore once copy/pasted why?', { 
  left: 10, 
  top: 50,
  fontFamily: 'Arial',
  fontSize: 20,
  fill: '#333'
});
canvas.add(text);


canvas.renderAll();


createListenersKeyboard();
function createListenersKeyboard() {
    document.onkeydown = onKeyDownHandler;
}

function onKeyDownHandler(event) {
    var key;
    if(window.event){
        key = window.event.keyCode;
    }
    else{
        key = event.keyCode;
    }

    switch(key){
        case 67: // Ctrl+C
                if(event.ctrlKey){
                    event.preventDefault();
                    copy();
                }
            break;
        case 86: // Ctrl+V
                if(event.ctrlKey){
                    event.preventDefault();
                    paste();
                }
            break;

        default:
            // TODO
            break;
    }
}

var copiedObject,
copiedObjects = new Array();
function copy(){
    copiedObjects = new Array();
    if(canvas.getActiveGroup()){
        canvas.getActiveGroup().getObjects().forEach(function(o){
            var object = fabric.util.object.clone(o);
            copiedObjects.push(object);
        });             
    }
    else if(canvas.getActiveObject()){
        var object = fabric.util.object.clone(canvas.getActiveObject());
        copiedObject = object;
        copiedObjects = new Array();
    }
}

function paste(){
    if(copiedObjects.length > 0){
        for(var i in copiedObjects){
            copiedObjects[i]=fabric.util.object.clone(copiedObjects[i]);
          copiedObjects[i].set("top", copiedObjects[i].top+100);
          copiedObjects[i].set("left", copiedObjects[i].left+100);
          canvas.add(copiedObjects[i]);
          canvas.item(canvas.size() - 1).hasControls = true;
        }                
    }
    else if(copiedObject){
        copiedObject= fabric.util.object.clone(copiedObject);
          copiedObject.set("top", 10);
        copiedObject.set("left", 10);
      canvas.add(copiedObject);
      canvas.item(canvas.size() - 1).hasControls = true;
    }
    canvas.renderAll();  
}

问题出在哪里?如何解决问题,以便我也可以复制/粘贴Itext并保持原样,而不是将其转换为简单文本?

2 个答案:

答案 0 :(得分:1)

没有深入研究FabricJS代码,我无法回答“为什么”(我猜这是你问题的一部分) - 但我相信如果你真的想知道你可以自己深入研究FabricJS代码。

但是,这是对您的代码的调整,以使其适合您:

function paste() {
  if (copiedObjects.length > 0) {
    for (var i in copiedObjects) {
      if (/text/.test(copiedObjects[i].type)) {
        canvas.add(new fabric.IText(copiedObjects[i].text, {
          left: copiedObjects[i].left + 100,
          top: copiedObjects[i].top + 100,
          fontFamily: copiedObjects[i].fontFamily,
          fontSize: copiedObjects[i].fontSize,
          fill: copiedObjects[i].fill
        }));
      } else {
        copiedObjects[i] = fabric.util.object.clone(copiedObjects[i]);
        copiedObjects[i].set("top", copiedObjects[i].top + 100);
        copiedObjects[i].set("left", copiedObjects[i].left + 100);
        canvas.add(copiedObjects[i]);
      }
      canvas.item(canvas.size() - 1).hasControls = true;
    }
  } else if (copiedObject) {
    if (/text/.test(copiedObject.type)) {
      canvas.add(new fabric.IText(copiedObject.text, {
        left: 10,
        top: 10,
        fontFamily: copiedObject.fontFamily,
        fontSize: copiedObject.fontSize,
        fill: copiedObject.fill
      }));
    } else {
      copiedObject = fabric.util.object.clone(copiedObject);
      copiedObject.set("top", 10);
      copiedObject.set("left", 10);
      canvas.add(copiedObject);
    }
    canvas.item(canvas.size() - 1).hasControls = true;
  }
  canvas.renderAll();
}

我的猜测,IText背后的基础对象实际上只是一个普通的旧Text对象,它有一个叠加层,使其能够响应键盘/鼠标事件。

这是你的JSFiddle更新,http://jsfiddle.net/7Hsdh/13/

希望有帮助,友好!

答案 1 :(得分:0)

你做错了什么。 fabric.util.object.clone旨在以吞咽方式克隆普通javascript对象。不是为了复制实例。

您必须使用Object.toObject创建对象的副本。

var canvas = new fabric.Canvas('paper');

var copiedObject,
copiedObjects = new Array();

function copy(){
    copiedObjects = new Array();
    if(canvas.getActiveGroup()){
        canvas.getActiveGroup().getObjects().forEach(function(o){
            var object = o.toObject();
            copiedObjects.push(object);
        });             
    }
    else if(canvas.getActiveObject()){
        var object = canvas.getActiveObject().toObject();
        copiedObject = object;
        copiedObjects = new Array();
    }
}

function paste(){
    if(copiedObjects.length > 0){
        for(var i in copiedObjects){
          copiedObjects[i].top += 100;
          copiedObjects[i].left += 100;
          var className = copiedObjects[i].type.slice(0, 1).toUpperCase() + copiedObjects[i].type.slice(1);
          fabric[className].fromObject(copiedObjects[i], function() {
            canvas.add();
          });
        }                
    }
    else if(copiedObject){
       .... do the same without the the for loop ....
    }
}