Html 使用 Fabric.js 的交互式文本字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10009080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 23:33:03  来源:igfitidea点击:

Interactive text fields with Fabric.js

htmltextcanvasfabricjs

提问by Kappei

I've been playing with Fabric.js a lot in the last few weeks, but regarding text fields I've only found it possible to set the text on creation.

在过去的几周里,我一直在使用 Fabric.js,但关于文本字段,我只发现可以在创建时设置文本。

Is there any possible way to make an interactive text field, or do I have to find a workaround to achieve that? (With interactive text field I mean an area of the canvas I can click on and write directly into it.)

是否有任何可能的方法来制作交互式文本字段,或者我是否必须找到一种解决方法来实现这一目标?(对于交互式文本字段,我指的是画布的一个区域,我可以单击并直接在其中写入。)

回答by melwyn pawar

The latest version of fabric.js includes a class IText which incorporates the interaction for editing and selection of text dynamically. try the code below with the latest version of fabric.js

最新版本的 fabric.js 包括一个 IText 类,它结合了动态编辑和选择文本的交互。使用最新版本的 fabric.js 尝试下面的代码

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

回答by Tyson

I recently built a mind mapping tool using fabric.js and I encountered the same problem.

我最近使用fabric.js 构建了一个思维导图工具,我遇到了同样的问题。

To achieve what you have described (changing the text on and after creation of textual elements in the canvas), I used jquery to detect the keydown event. Assuming you have selected the desired textual element in the fabric canvas the following snippet will change the text.

为了实现您所描述的(在画布中创建文本元素时和之后更改文本),我使用 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;
        }
    }
});

Using this technique, I can select a text element in the fabric canvas, begin typing and the text is replaced. You could change it so it didn't erase the text each time you select the element.

使用这种技术,我可以在织物画布中选择一个文本元素,开始输入并替换文本。您可以更改它,这样每次选择元素时它都不会擦除文本。

There are some compromises with this method. For example you cannot select text as if it were in a regular HTML input text element and there is no blinking cursor, therefore the "virtual" cursor is always at the end of the text.

这种方法有一些妥协。例如,您不能像在常规 HTML 输入文本元素中一样选择文本,并且没有闪烁的光标,因此“虚拟”光标始终位于文本的末尾。

If you really wanted to you could draw a blinking cursor at the end of the text.

如果您真的愿意,可以在文本末尾绘制一个闪烁的光标。

回答by pawan jain

I guess its too late, but this might be of help to others.

我想为时已晚,但这可能对其他人有所帮助。

There is a demo on fabricjs to do the exact same thing.

有一个关于 fabricjs 的演示来做完全相同的事情。

回答by Kim Jansson

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

That was what I was looking for :) Thanks alot!

这就是我要找的 :) 非常感谢!

回答by Kalvin Klien

Try this(this is from my 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,
        });

回答by Saturnix

assuming you have both the canvas and the context as variables in your 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);