web-dev-qa-db-fra.com

Champs de texte interactifs avec Fabric.js

J'ai beaucoup joué avec Fabric.js ces dernières semaines, mais en ce qui concerne les champs de texte, je n'ai trouvé que la possibilité de définir le texte à la création.

Est-il possible de créer un champ de texte interactif ou dois-je trouver une solution de contournement pour y parvenir? (Par champ de texte interactif, je veux dire une zone de la toile sur laquelle je peux cliquer et écrire directement.)

24
Kappei

La dernière version de fabric.js comprend une classe IText qui intègre l’interaction pour l’édition et la sélection dynamique de texte. essayez le code ci-dessous avec la dernière version de fabric.js

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

J'ai récemment construit un outil de cartographie conceptuelle à l'aide de fabric.js et j'ai rencontré le même problème. 

Pour réaliser ce que vous avez décrit (modification du texte sur et après la création d'éléments textuels dans le canevas), j'ai utilisé jquery pour détecter l'événement de raccourci. En supposant que vous ayez sélectionné l'élément textuel souhaité dans le canevas du tissu, l'extrait suivant modifiera le texte.

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

En utilisant cette technique, je peux sélectionner un élément de texte dans le canevas, commencer à taper et le texte est remplacé. Vous pouvez le changer pour ne pas effacer le texte chaque fois que vous sélectionnez l'élément.

Il y a quelques compromis avec cette méthode. Par exemple, vous ne pouvez pas sélectionner du texte comme s'il s'agissait d'un élément de saisie HTML ordinaire et si aucun curseur ne clignote, le curseur "virtuel" se trouve donc toujours à la fin du texte.

Si vous le désirez vraiment, vous pouvez dessiner un curseur clignotant à la fin du texte.

14
Tyson

Je suppose que c'est trop tard, mais cela pourrait aider d'autres.

Il y a une démo sur fabricjs pour faire la même chose.

2
pawan jain
    text.set({ text: newText }); //Change the text
    canvas.renderAll(); //Update the canvas

C'était ce que je cherchais :) Merci beaucoup!

2
Kim Jansson

Essayez ceci (cela provient de mon application):

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,
        });
0
Kalvin Klien

en supposant que vous avez à la fois la toile et le contexte comme variables dans votre 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
Saturnix