web-dev-qa-db-ja.com

Fabric.jsを使用したインタラクティブテキストフィールド

ここ数週間、Fabric.jsを何度も使っていますが、テキストフィールドに関しては、作成時にテキストを設定することしかできませんでした。

インタラクティブなテキストフィールドを作成する方法はありますか?それを達成するための回避策を見つける必要がありますか? (インタラクティブテキストフィールドとは、クリックして直接書き込むことができるキャンバスの領域を意味します。)

24
Kappei

Fabric.jsの最新バージョンには、テキストの動的な編集と選択のための相互作用を組み込んだクラスITextが含まれています。次のコードを最新バージョンのfabric.jsで試してください

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

私は最近、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入力テキスト要素にあるかのようにテキストを選択できず、点滅カーソルがないため、「仮想」カーソルは常にテキストの末尾にあります。

本当にしたい場合は、テキストの最後に点滅するカーソルを描くことができます。

14
Tyson

手遅れだと思いますが、これは他の人の助けになるかもしれません。

まったく同じことを行うためのfabricjsのデモがあります

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

それが私が探していたものでした:)ありがとうございます!

2
Kim Jansson

これを試してください(これは私のアプリケーションからです):

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

スクリプトの変数としてキャンバスとコンテキストの両方があると仮定します。

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