2012-04-04 12 views
23

Ho giocato molto con Fabric.js nelle ultime settimane, ma per quanto riguarda i campi di testo ho trovato solo la possibilità di impostare il testo sulla creazione.Campi di testo interattivi con Fabric.js

Esiste un modo per creare un campo di testo interattivo o devo trovare una soluzione alternativa per raggiungere questo obiettivo? (Con campo di testo interattivo intendo una superficie di tela che posso fare clic su e scrivere direttamente in esso.)

+1

cosa intendi per campo di testo interattivo? – hjpotter92

+0

@TheJumpingFrog: Significa aggiungere testo alla tela e modificarne il contenuto in seguito. – Marcel

+0

Esattamente quello che Marcel ha detto – Kappei

risposta

59

L'ultima versione di fabric.js include una classe IText che incorpora l'interazione per la modifica e la selezione del testo in modo dinamico. provare il codice qui sotto con l'ultima versione di fabric.js

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

Upvote come offrire una risposta migliore e più aggiornata. –

+3

Vale la pena notare che questo è stato introdotto in fabric.js 1.4. Di recente ho creato una build personalizzata con tutto e IText non si trovava in quella build quindi ricevevo errori di 'function is undefined'. Ho cambiato la mia fonte di script in modo che punti al cdn, 'http: // cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js' invece della mia copia locale e che ha risolto il mio problema. Non sono ancora sicuro del motivo per cui IText non sia nella build personalizzata. – teewuane

+0

Questo è un Life saver –

0

assumendo che abbiate la tela e il contesto come variabili nello script:

// 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

Questo non è quello che sto cercando. So come impostare un testo in una tela, quello che ho chiesto era un modo per ottenere un campo di testo _interactive_ con fabricjs, se possibile: con campo di testo interattivo intendo un'area della tela su cui posso cliccare e scriverla direttamente . (Modificata la domanda originale per chiarezza) – Kappei

14

I recentemente ho creato uno strumento di mind mapping usando fabric.js e ho riscontrato lo stesso problema.

Per ottenere ciò che hai descritto (cambiando il testo su e dopo la creazione di elementi testuali nell'area di disegno), ho usato jquery per rilevare l'evento keydown. Supponendo di aver selezionato l'elemento testuale desiderato nell'area di tessuto, il seguente frammento cambierà il testo.

$(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; 
     } 
    } 
}); 

Utilizzando questa tecnica, posso selezionare un elemento di testo nella tela tessuto, e iniziare a digitare il testo viene sostituito. Puoi cambiarlo in modo che non cancelli il testo ogni volta che selezioni l'elemento.

Ci sono alcuni compromessi con questo metodo. Ad esempio, non è possibile selezionare il testo come se fosse in un normale elemento di testo di input HTML e non vi è alcun cursore lampeggiante, pertanto il cursore "virtuale" si trova sempre alla fine del testo.

Se si voleva davvero si potrebbe disegnare un cursore lampeggiante alla fine del testo.

+0

Grazie mille. Come pensavo, sembra che non ci sia una tecnica integrata per farlo in modo nativo in fabricjs. Questo è esattamente il tipo di soluzione a cui stavo pensando. – Kappei

+0

Straordinario pezzo di codice Tyson, ho appena corretto un piccolo bug per quando un utente ha premuto il tasto Maiusc da solo (stava cancellando il testo). Ho appena aggiunto un altro se non farlo fare niente. –

+0

Non riesco comunque ad inserire caratteri speciali. C'è una soluzione per questo? Inoltre, la funzione "canvasBeforeSelectionCleared()" non è definita. – Siddhant

0

Prova questa (questo è dalla mia applicazione):

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 

che era quello che stavo cercando :) Grazie mille!

Problemi correlati