Interaktive Textfelder mit Fabric.js

Lesezeit: 6 Minuten

Benutzer-Avatar
Kappei

Ich habe in den letzten Wochen viel mit Fabric.js herumgespielt, aber bei Textfeldern habe ich festgestellt, dass es nur möglich ist, den Text bei der Erstellung festzulegen.

Gibt es eine Möglichkeit, ein interaktives Textfeld zu erstellen, oder muss ich eine Problemumgehung finden, um dies zu erreichen? (Mit interaktivem Textfeld meine ich einen Bereich der Leinwand, auf den ich klicken und direkt hineinschreiben kann.)

  • Was meinst du mit interaktivem Textfeld?

    – hjpotter92

    4. April 2012 um 10:13 Uhr

  • @TheJumpingFrog: Er meint, Text zur Leinwand hinzuzufügen und den Inhalt später zu bearbeiten.

    – Marcel

    4. April 2012 um 10:19 Uhr

  • Genau das, was Marcel gesagt hat

    – Kappei

    4. April 2012 um 10:24 Uhr

  • Was ist das Protokoll hier, wenn eine Antwort veraltet ist? Eine neue Frage erstellen, beantworten und von der ursprünglichen Frage aus auf diese Frage verlinken? Grundsätzlich ist die akzeptierte Antwort nicht mehr richtig und die Antwort darunter ist die richtige Antwort für Leute, die nach einer Lösung suchen.

    – teewuane

    18. Juni 2014 um 19:04 Uhr

  • @teewuane Sie können die Frage einfach kommentieren (wie Sie es getan haben) und den Autor benachrichtigen, dass es eine aktuellere Antwort gibt. Das Ändern der akzeptierten Antwort ist nur eine Frage eines Klicks 🙂

    – Kappei

    19. Juni 2014 um 9:08 Uhr

Die neueste Version von fabric.js enthält eine Klasse IText, die die Interaktion zum Bearbeiten und Auswählen von Text dynamisch enthält. Probieren Sie den folgenden Code mit der neuesten Version von fabric.js aus

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

  • Stimmen Sie positiv ab, da Sie eine bessere und aktuellere Antwort anbieten.

    – Pherrymason

    27. Mai 2014 um 11:39 Uhr

  • Es ist erwähnenswert, dass dies in fabric.js 1.4 eingeführt wurde. Ich habe kürzlich einen benutzerdefinierten Build mit allem erstellt und IText war nicht in diesem Build, also bekam ich function is undefined-ähnliche Fehler. Ich habe meine Skriptquelle so geändert, dass sie auf das cdn zeigt, http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js anstelle meiner eigenen lokalen Kopie und das hat mein Problem behoben. Ich bin mir immer noch nicht sicher, warum IText nicht im benutzerdefinierten Build enthalten ist.

    – teewuane

    18. Juni 2014 um 19:02 Uhr

  • Danke dafür. Wie kann ich neue Steuerelemente zu Text- oder IText-Objekten hinzufügen? Ich möchte Farbwähler, Fett, Kursiv, Unterstrichen, Schriftartauswahl usw. anzeigen, wenn der Benutzer auf das Textfeld klickt. Gibt es da irgendwelche Plugins dafür?

    – Ashit Vora

    22. Februar 2015 um 5:52 Uhr

  • Hallo, Sie können einen Farbwähler hinzufügen, indem Sie auf das erstellte Objekt verweisen und seine Farbeigenschaft auschecken letztroll.com/#!/create Wenn Sie auf das Textwerkzeug aus der Werkzeugbox klicken, wird ein Textfeld sowie eine Referenzebene erstellt, die sich auf das Textobjekt beziehen kann

    – Melwyn Pawar

    23. Februar 2015 um 18:42 Uhr

  • Können Sie vorschlagen, wie Sie mit dem Schreiben von Text an einer bestimmten Koordinate beginnen? @melwynpawr

    – Amanjot Kaur

    2. November 2015 um 10:48 Uhr

Benutzer-Avatar
Tyson

Ich habe kürzlich ein Mind-Mapping-Tool mit fabric.js erstellt und bin auf dasselbe Problem gestoßen.

Um das zu erreichen, was Sie beschrieben haben (Ändern des Textes bei und nach der Erstellung von Textelementen in der Leinwand), habe ich jquery verwendet, um das Keydown-Ereignis zu erkennen. Angenommen, Sie haben das gewünschte Textelement in der Stoffleinwand ausgewählt, ändert der folgende Ausschnitt den Text.

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

Mit dieser Technik kann ich ein Textelement auf der Stoffleinwand auswählen, mit der Eingabe beginnen und der Text wird ersetzt. Sie können es ändern, damit der Text nicht jedes Mal gelöscht wird, wenn Sie das Element auswählen.

Bei dieser Methode gibt es einige Kompromisse. Beispielsweise können Sie Text nicht wie in einem normalen HTML-Eingabetextelement auswählen und es gibt keinen blinkenden Cursor, daher befindet sich der “virtuelle” Cursor immer am Ende des Textes.

Wenn Sie wirklich wollten, könnten Sie am Ende des Textes einen blinkenden Cursor zeichnen.

  • Danke vielmals. Wie ich dachte, scheint es keine eingebaute Technik zu geben, um dies nativ in fabricjs zu tun. Das ist genau die Art von Workaround, an die ich gedacht habe.

    – Kappei

    10. April 2012 um 7:44 Uhr


  • Tolles Stück Code Tyson, ich habe gerade einen kleinen Fehler behoben, als ein Benutzer die Umschalttaste selbst drückte (es löschte den Text). Ich habe gerade ein else if hinzugefügt, damit es nichts tut

    – Brett Gregson

    11. November 2012 um 22:16 Uhr

  • Allerdings kann ich keine Sonderzeichen eingeben. Gibt es dafür eine Lösung? Auch die Funktion “canvasBeforeSelectionCleared()” ist nicht definiert.

    – Siddhant

    26. Dezember 2012 um 7:12 Uhr


  • Ich habe diesen Code verwendet, es funktioniert gut, aber in der Textfeld-Leinwand wird der Cursor nicht angezeigt? @Kappei

    – Sanjay Nakate

    19. Oktober 2013 um 10:19 Uhr

Benutzer-Avatar
pawan jain

Ich denke, es ist zu spät, aber vielleicht hilft es anderen.

Es gibt eine Demo auf fabricjs, um genau dasselbe zu tun.

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

Das war, wonach ich gesucht habe 🙂 Vielen Dank!

Angenommen, Sie haben sowohl die Leinwand als auch den Kontext als Variablen in Ihrem Skript:

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

  • Das ist nicht das, wonach ich suche. Ich weiß, wie man einen Text in eine Leinwand einfügt, was ich wollte, war eine Möglichkeit, einen zu bekommen interaktiv Textfeld mit fabricjs, wenn möglich: mit interaktivem Textfeld meine ich einen Bereich der Leinwand, auf den ich klicken und direkt hineinschreiben kann. (Die ursprüngliche Frage wurde zur Verdeutlichung geändert.)

    – Kappei

    5. April 2012 um 8:07 Uhr

Benutzer-Avatar
Kalvin Klien

Versuchen Sie dies (dies ist aus meiner Anwendung):

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

  • Das ist nicht das, wonach ich suche. Ich weiß, wie man einen Text in eine Leinwand einfügt, was ich wollte, war eine Möglichkeit, einen zu bekommen interaktiv Textfeld mit fabricjs, wenn möglich: mit interaktivem Textfeld meine ich einen Bereich der Leinwand, auf den ich klicken und direkt hineinschreiben kann. (Die ursprüngliche Frage wurde zur Verdeutlichung geändert.)

    – Kappei

    5. April 2012 um 8:07 Uhr

1098850cookie-checkInteraktive Textfelder mit Fabric.js

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy