2012-04-04 145 views
23

在過去的幾周裏,我一直在玩Fabric.js,但關於文本字段,我只發現可以在創建時設置文本。Fabric.js的交互式文本字段

是否有任何可能的方式來創建一個交互式文本字段,還是我必須找到一個解決方法來實現這一目標? (隨着交互文本字段我的意思是畫布的一個區域,我可以點擊直接寫進去。)

+1

什麼叫交互式文本字段是什麼意思? – hjpotter92 2012-04-04 10:13:13

+0

@TheJumpingFrog:他意味着將文本添加到畫布並稍後編輯它的內容。 – Marcel 2012-04-04 10:19:53

+0

Marcel說的是什麼 – Kappei 2012-04-04 10:24:42

回答

59

fabric.js的最新版本包含一個類IText,它結合了用於動態編輯和選擇文本的交互。請試試下面的代碼與最新版本的fabric.js

canvas.add(new fabric.IText('Tap and Type', { 
    fontFamily: 'arial black', 
    left: 100, 
    top: 100 , 
})); 
+0

Upvote提供更好,更新的答案。 – 2014-05-27 11:39:59

+3

值得注意的是,這是在fabric.js 1.4中引入的。我最近做了一個自定義的構建和IText不在那個構建,所以我得到'功能是未定義的錯誤。我將腳本源改爲指向cdn,'http:// cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js'而不是我自己的本地副本,並修復了我的問題問題。我仍然不確定爲什麼IText不在自定義版本中。 – teewuane 2014-06-18 19:02:36

+0

這是救生員 – 2014-12-18 03:37:28

0

假設你同時在畫布和上下文關係中腳本變量:

// write text 
context.fillText("text1",0,0); 


// refresh canvas and write new text 
context.clearRect(0,0,canvas.width,canvas.height); 
context.fillText("text2",0,0); 
+0

這不是我要找的。我知道如何在畫布中設置文本,如果可能,我要求的方法是使用fabricjs獲取_interactive_文本字段:使用交互式文本字段我指的是可以單擊並直接寫入畫布的區域。 (爲了清晰起見修改了原始問題) – Kappei 2012-04-05 08:07:34

14

我最近使用fabric.js構建了一個思維導圖工具,我遇到了同樣的問題。

爲了實現您所描述的內容(在畫布中創建文本元素之後和之後更改文本),我使用jquery來檢測keydown事件。假設您已在布料畫布中選擇了所需的文本元素,以下片段將更改文本。

$(document).keydown(function(e){ 
    var keyPressed = String.fromCharCode(e.which); 
    var text = canvas.getActiveObject(); 
    if (text) 
    { 
     var newText = ''; 
     var stillTyping = true; 
     if (e.which == 27) //esc 
     { 
      if (!text.originalText) return; //if there is no original text, there is nothing to undo 
      newText = text.originalText; 
      stillTyping = false; 
     } 
     //if the user wants to make a correction 
     else 
     { 
      //Store the original text before beginning to type 
      if (!text.originalText) 
      { 
       text.originalText = text.text; 
      } 
      //if the user wants to remove all text, or the element entirely 
      if (e.which == 46) //delete 
      { 
       activeObject.element.remove(true); 
       return; 
      } 
      else if (e.which == 16) { //shift 
       newText = text.text; 
      } 
      else if (e.which == 8) //backspace 
      { 
       e.preventDefault(); 
       newText = text.text.substr(0, text.text.length - 1); 
      } 
      else if (e.which == 13) //enter 
      { 
       //canvas clear selection 
       canvas.discardActiveObject(); 
       canvas.renderAll(); 
       canvasBeforeSelectionCleared({ memo: { target: text} }); 

       newText = text.text; 
       stillTyping = false; 
      } 
      //if the user is typing alphanumeric characters 
      else if (
       (e.which > 64 && e.which < 91) || //A-Z 
       (e.which > 47 && e.which < 58) || //0-9 
       (e.which == 32) || //Space 
       (keyPressed.match(/[!&()"'?-]/)) //Accepted special characters 
      ) 
      { 
       if (text.text == text.originalText) text.text = ''; 
       if (keyPressed.match(/[A-Z]/) && !e.shiftKey) 
        keyPressed = keyPressed.toLowerCase(); 
       newText = text.text + keyPressed; 
      } 
     } 
     text.set({ text: newText }); //Change the text 
     canvas.renderAll(); //Update the canvas 

     if (!stillTyping) 
     { 
      this.text.originalText = null; 
     } 
    } 
}); 

使用這種技術,我可以選擇面料畫布中的文本元素,開始輸入並替換文本。您可以更改它,以便每次選擇元素時都不會擦除文本。

這種方法有一些妥協。例如,您不能選擇文本,就好像它是在常規的HTML輸入文本元素中一樣,並且沒有閃爍的光標,因此「虛擬」光標始終位於文本的末尾。

如果你真的想要你可以在文本的末尾畫一個閃爍的光標。

+0

非常感謝。 正如我的想法,似乎沒有內置的技術在fabricjs中本地執行此操作。 這正是我想到的解決方法。 – Kappei 2012-04-10 07:44:09

+0

Tyson的一段代碼非常棒,我只是修復了一個小錯誤,當用戶按下shift鍵時(它正在清除文本)。我只是添加了一個其他的東西,如果使它無效 – 2012-11-11 22:16:17

+0

雖然我不能輸入特殊字符。有沒有解決這個問題? 此外,函數「canvasBeforeSelectionCleared()」未定義。 – Siddhant 2012-12-26 07:12:20

0

試試這個(這是從我的應用程序):

Text Color: <input id="text-color" type="text" value = "#FF0000" name="textColor" /> 


textColor.onchange = function() { 
      canvas.getActiveObject().setColor(this.value); 
      canvas.renderAll(); 
     }; 

function updateControls() {   
      textControl.value = canvas.getActiveObject().getText(); 
     } 

     canvas.on({ 
      'object:selected': updateControls, 
     }); 
2
text.set({ text: newText }); //Change the text 
    canvas.renderAll(); //Update the canvas 

那正是我一直在尋找:)非常感謝!