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

问题描述 投票:0回答:7

过去几周我经常使用 Fabric.js,但对于文本字段,我只发现可以在创建时设置文本。

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

html text canvas fabricjs
7个回答
89
投票

fabric.js 的最新版本包含一个 IText 类,它集成了动态编辑和选择文本的交互。使用最新版本的 Fabric.js 尝试以下代码

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

15
投票

我最近使用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 输入文本元素中一样选择文本,并且没有闪烁的光标,因此“虚拟”光标始终位于文本的末尾。

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


5
投票

我想已经太晚了,但这可能对其他人有帮助。

fabricjs 上有一个演示可以做同样的事情。


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

这就是我一直在寻找的:)非常感谢!


0
投票

假设您将画布和上下文都作为脚本中的变量:

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

试试这个(这是来自我的应用程序):

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
投票

Fabric 有一个交互式文本对象。

const sample = "lorem ipsum";
const itext = fabric.IText(sample, {left: 0, top: 0});

注意

要编辑文本,请双击文本字段进入编辑模式

© www.soinside.com 2019 - 2024. All rights reserved.