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

Html 使用Fabric.js的交互式文本字段,html,text,canvas,fabricjs,Html,Text,Canvas,Fabricjs,在过去的几周里,我一直在使用Fabric.js,但是关于文本字段,我发现只有在创建时才能设置文本 是否有任何可能的方法来创建一个交互式文本字段,或者我必须找到一个解决方法来实现这一点?(对于交互式文本字段,我指的是画布上可以单击并直接写入的区域。)假设脚本中有画布和上下文作为变量: // write text context.fillText("text1",0,0); // refresh canvas and write new text context.clearRect(0,0,ca

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


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

假设脚本中有画布和上下文作为变量:

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

我最近使用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;
        }
    }
});
$(文档).keydown(函数(e){
var keyPressed=String.fromCharCode(e.which);
var text=canvas.getActiveObject();
如果(文本)
{
var newText='';
var=true;
如果(e.which==27)//esc
{
如果(!text.originalText)返回;//如果没有原始文本,则没有要撤消的内容
newText=text.originalText;
stillTyping=false;
}
//如果用户想要进行更正
其他的
{
//在开始键入之前存储原始文本
如果(!text.originalText)
{
text.originalText=text.text;
}
//如果用户希望删除所有文本或整个元素
如果(e.which==46)//删除
{
activeObject.element.remove(true);
返回;
}
如果(e.which==16){//shift
newText=text.text;
}
else如果(e.which==8)//退格
{
e、 预防默认值();
newText=text.text.substr(0,text.text.length-1);
}
如果(e.which==13)//输入
{
//画布清除选择
canvas.discardActiveObject();
canvas.renderAll();
canvasBeforeSelectionCleared({memo:{target:text}});
newText=text.text;
stillTyping=false;
}
//如果用户正在键入字母数字字符
否则如果(
(e.which>64&&e.which<91)| |//A-Z
(e.which>47&&e.which<58)|//0-9
(e.which==32)| |//空格
(按keyPressed.match(//[!&()“?-]/)//接受的特殊字符
)
{
如果(text.text==text.originalText)text.text='';
if(按下键。匹配(/[A-Z]/)&&&!e.shiftKey)
keyPressed=keyPressed.toLowerCase();
newText=text.text+按键;
}
}
text.set({text:newText});//更改文本
canvas.renderAll();//更新画布
如果(!仍然键入)
{
this.text.originalText=null;
}
}
});
使用这种技术,我可以在fabric画布中选择一个文本元素,开始键入并替换文本。您可以更改它,使它不会在每次选择该元素时删除文本

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

$(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;
        }
    }
});
如果你真的想,你可以在文本的末尾画一个闪烁的光标。

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

$(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;
        }
    }
});
文本颜色:
textColor.onchange=函数(){
canvas.getActiveObject().setColor(this.value);
canvas.renderAll();
};
函数updateControl(){
textControl.value=canvas.getActiveObject().getText();
}
帆布({
“对象:选定”:UpdateControl,
});

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

最新版本的fabric.js包含一个类IText,该类包含用于动态编辑和选择文本的交互。请使用最新版本的fabric.js尝试下面的代码

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

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


你所说的交互式文本字段是什么意思?@TheJumpingFrog:他的意思是在画布上添加文本,稍后编辑其内容。正如Marcel所说,当答案过期时,这里的协议是什么?创建一个新问题,回答它,并从原始问题链接到该问题?基本上,已接受的答案不再正确下面的答案对于正在寻找解决方案的人来说是正确的。@teewuane你可以简单地对这个问题发表评论(就像你做的那样)并通知作者有一个更为最新的答案。更改接受的答案只需单击一下即可:)这不是我想要的。我知道如何在画布中设置文本,我要求的是一种使用fabricjs获得交互式文本字段的方法,如果可能的话:使用交互式文本字段,我指的是可以单击的画布区域打开并直接写入。(为了清晰起见修改了原始问题)非常感谢。正如我所想,似乎在fabricjs中没有内置的技术来实现这一点。这正是我所想的解决方法。太棒了,泰森,我刚刚修复了一个小错误,当用户自己按下shift键时(正在清除文本)。我刚刚添加了一个else if,使其不起任何作用。但是我无法输入特殊字符。是否有解决方法?还有,函数“canvasBeforeSelectionCleared()“未定义。我使用了此代码,它工作正常,但在编辑文本字段画布中未显示光标?@KappeiUpvote提供了更好、更高的