3

我正在尝试创建类似于http://www.listings.com的内容,您可以在其中编辑画布中的文本。

我读过另一篇文章HTML5 Canvas Text Edit。但我不想在画布之外编辑文本。我想编辑画布中的文本。

如果有人能指出我正确的方向,我将不胜感激。
谢谢

4

3 回答 3

7

首先,Mohsen 正确地指出,当您执行 context.fillText 时,您实际上是在画布上“绘制字母图片”。它不像文字处理器!

您可以捕获窗口上的键事件,然后将击键写到画布上。

这是代码和小提琴:http: //jsfiddle.net/m1erickson/7tXd4/

此示例仅键入小写 az(无大写、空格、退格等)

您可能希望进行更多增强,如下所示:

  • 添加更多键(AZ、0-9 等)。
  • 响应退格键等命令键以从 keyHistory 中删除字母。
  • 放置一个光标,以便用户在输入时知道他们在哪一行(提示:http ://www.html5canvastutorials.com/tutorials/html5-canvas-text-metrics/ )
  • 如果您允许多行文本,请处理 [enterkey] 并移动到新行。
  • ETC

这里的代码只是为了让你开始

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    ctx.font="18px Arial";

    var keyHistory="";

    window.addEventListener("keyup", keyUpHandler, true);

    function addletter(letter){
        keyHistory+=letter;
        ctx.clearRect(0,0,300,300);
        ctx.fillText(keyHistory,20,20);
    }

    function keyUpHandler(event){
        var letters="abcdefghijklmnopqrstuvwxyz";
        var key=event.keyCode;
        if(key>64 && key<91){
            var letter=letters.substring(key-64,key-65);
            addletter(letter);
        }
    }

}); // end $(function(){});
</script>

</head>

<body>
    <p>First click in the red canvas below</p><br/>
    <p>Then type any lowercase letters from a-z</p><br/>
    <canvas id="canvas" width=300 height=100></canvas>
</body>
</html>
于 2013-04-05T01:29:10.963 回答
3

fillText()不要创建以后可以编辑的对象或文本节点。它将在画布上填充文本,这意味着它将在画布上留下像素。

您可以使用诸如http://kineticjs.com/之类的 Canvas 库为该文本创建一个图层,这样您就可以擦除该图层并在其中重新键入文本。Kinect 允许您将值绑定到图层,以便您可以保存您拥有的文本在层中绑定到层的值。

于 2013-04-04T23:25:23.957 回答
0

试试这个解决方案https://jsfiddle.net/tabvn/zjyoexf1/

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Canvas Input Element</title>
</head>
<body>
    <canvas id="draw" width="500" height="500"></canvas>
<script type="text/javascript">
    var canvas = document.getElementById("draw");
    var ctx = canvas.getContext("2d");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    ctx.beginPath();

    function Input(text = "", options = {}){
        this.text = text;
        this.options = Object.assign({width: 250, height: 40, font: "17px Arial", borderWidth: 1, borderColor: "#ccc", padding: 5}, options);
        this.position = {x: 10, y: 10};
        this.isFocus = false;
        this.focusIndex = text.length;
        this.isCommandKey = false;
        this.selected = false;

        this.render = function(){
            ctx.clearRect(this.position.x, this.position.y, this.options.width, this.options.height);
            ctx.font = this.options.font;
            ctx.lineWidth = this.options.borderWidth;
            ctx.strokeStyle = this.options.borderColor;
            if(this.isFocus){
                ctx.strokeStyle = "#000";
            }
            ctx.rect(this.position.x, this.position.y, this.options.width, this.options.height);
            ctx.stroke();

            // write text
            var str = "";
            for(var i = 0; i < this.text.length; i++){
                if(!this.selected && this.isFocus && this.focusIndex === i){
                    str += "|";
                }
                str += this.text[i];
            }
            if(!this.selected && this.isFocus && this.focusIndex === this.text.length){
                str += "|";
            }

            if(this.selected){
                    var _width = ctx.measureText(this.text).width;
                    ctx.fillStyle = 'rgba(0,0,0,0.5)';
                    ctx.fillRect(this.position.x + this.options.padding, this.position.y + this.options.padding, _width, parseInt(this.options.font, 17));

            }

            ctx.fillStyle = "#000";
            ctx.fillText(str, this.position.x + this.options.padding,  this.position.y + (this.options.height / 2) + this.options.padding);

        }

        this.handleOnClick = function(e){
            let clientX = e.clientX;
            let clientY = e.clientY;
            if(clientX <= this.position.x + this.options.width && clientX >= this.position.x && clientY <= this.position.y + this.options.height && clientY >= this.position.y){
                if(!this.isFocus){
                    this.isFocus = true;
                    this.focusIndex = this.text.length;
                    this.render();
                }
            }else{
                if(this.isFocus){
                    this.selected = false;
                    this.isFocus = false;
                    this.render();
                }

            }
        }

        this.handleOnKeyUp = function(e){
            this.isCommandKey = false;
            this.render();
        }

        this.handleOnKeyDown = function(e){
            if(e.key === "Meta" || e.key === "Control"){
                this.isCommandKey = true;
            }
            if(this.isFocus){
                e.preventDefault();
            }
            if(this.isCommandKey && e.key === "a"){
                this.selected = true;
                this.render(); 
                return 
            }
            if(this.isFocus && e.key === "Backspace"){
                if(this.selected){
                    this.focusIndex = 0;
                    this.text = "";
                    this.selected = false;
                    this.render();
                }
                var str = "";
                for(var i =0; i < this.text.length; i++){
                    if(i !== this.focusIndex - 1){
                        str += this.text[i];
                    }
                }

                this.text = str;

                this.focusIndex --;
                if(this.focusIndex <0){
                    this.focusIndex = 0;
                }
                this.render();
            }
            if(this.isFocus && e.key === "ArrowLeft"){
                this.focusIndex --;
                if(this.focusIndex < 0){
                    this.focusIndex = 0;
                }
                this.render();
            }
            if(this.isFocus && e.key === "ArrowRight"){
                this.focusIndex ++;
                if(this.focusIndex > this.text.length){
                    this.focusIndex = this.text.length;
                }
                this.render();
            }
            if(!this.isCommandKey && this.isFocus && (e.keyCode == 32 || (e.keyCode >= 65))){
                this.text += e.key;
                this.focusIndex = this.text.length;
                this.render();
            }


        }
    }

    var input = new Input("I 'm an input");
    input.render();

    window.addEventListener("click", function(event){
            input.handleOnClick(event);
    });
    window.addEventListener("keydown", function(event){
            input.handleOnKeyDown(event);
    });
    window.addEventListener("keyup", function(event){
            input.handleOnKeyUp(event);
    });

</script>

</body>
</html>
于 2019-11-10T05:04:40.507 回答