将多个文本实例添加到HTML5画布

时间:2014-02-22 06:35:08

标签: javascript html5 text canvas

我在互联网上找到了这个代码并一直在玩它。它将文本添加到画布上的任何点。这很好,但是当新的文本添加到画布时,前一个文本被删除。是否有一种简单的方法可以同时在画布上存在多个文本实例?

我是JS的新手,在保存新文本后删除文本的代码中看不到任何内容。我真的希望我不必将数据中的所有文本与x和y坐标一起保存,我就没那么熟练了。

我正在使用的代码如下,但没有一些外部JS就无法工作,所以这里是我复制它的工作版本的链接。 http://oldstatic.travisberry.com/demos/canvas-text-demo/index.html

提前感谢任何建议

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/css.css">
</head>
<body>
    <div id="main">
        <canvas id="c"></canvas><!-- the canvas -->
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript" src="text.js"></script><!-- Library to help text -->
    <script type="text/javascript">
$('#c').mousedown(function(e){
            if ($('#textAreaPopUp').length == 0) {
                var mouseX = e.pageX - this.offsetLeft + $("#c").position().left;
                var mouseY = e.pageY - this.offsetTop;

                //append a text area box to the canvas where the user clicked to enter in a comment
                var textArea = "<div id='textAreaPopUp' style='position:absolute;top:"+mouseY+"px;left:"+mouseX+"px;z-index:30;'><textarea id='textareaTest' style='width:100px;height:50px;'></textarea>";
                var saveButton = "<input type='button' value='save' id='saveText' onclick='saveTextFromArea("+mouseY+","+mouseX+");'></div>";
                var appendString = textArea + saveButton;
                $("#main").append(appendString);
            } else {
                $('textarea#textareaTest').remove();
                $('#saveText').remove();
                //$('#textAreaPopUp').remove();
                var mouseX = e.pageX - this.offsetLeft + $("#c").position().left;
                var mouseY = e.pageY - this.offsetTop;
                //append a text area box to the canvas where the user clicked to enter in a comment
                var textArea = "<div id='textAreaPopUp' style='position:absolute;top:"+mouseY+"px;left:"+mouseX+"px;z-index:30;'><textarea id='textareaTest' style='width:100px;height:50px;'></textarea>";
                var saveButton = "<input type='button' value='save' id='saveText' onclick='saveTextFromArea("+mouseY+","+mouseX+");'></div>";
                var appendString = textArea + saveButton;
                $("#main").append(appendString);
            }
        });

        function saveTextFromArea(y,x){
            //get the value of the textarea then destroy it and the save button
            var text = $('textarea#textareaTest').val();
            $('textarea#textareaTest').remove();
            $('#saveText').remove();
            $('#textAreaPopUp').remove();
            //get the canvas and add the text functions
            var canvas = document.getElementById('c');
            var ctx = canvas.getContext('2d');
            var cw = canvas.clientWidth;
            var ch = canvas.clientHeight;
            canvas.width = cw;
            canvas.height = ch;
            //break the text into arrays based on a text width of 100px
            var phraseArray = getLines(ctx,text,100);
            // this adds the text functions to the ctx
            CanvasTextFunctions.enable(ctx);
            var counter = 0;
            //set the font styles
            var font = "sans";
            var fontsize = 12;
            ctx.strokeStyle = "rgba(0,0,0,1)";
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 0;
            ctx.shadowBlur = 0;
            ctx.shadowColor = "rgba(0,0,0,1)";
            //draw each phrase to the screen, making the top position 20px more each time so it appears there are line breaks
            $.each(phraseArray, function() {
                //set the placement in the canvas
                var lineheight = fontsize * 1.5;
                var newline = ++counter;
                newline = newline * lineheight;
                var topPlacement = y - $("#c").position().top + newline;
                var leftPlacement = x - $("#c").position().left;
                text = this;
                //draw the text
                ctx.drawText(font, fontsize, leftPlacement, topPlacement, text);
                ctx.save();
                ctx.restore();
            });
            //reset the drop shadow so any other drawing don't have them
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 0;
            ctx.shadowBlur = 0;
            ctx.shadowColor = "rgba(0,0,0,0)";
        }

        function getLines(ctx,phrase,maxPxLength) {
            //break the text area text into lines based on "box" width
            var wa=phrase.split(" "),
            phraseArray=[],
            lastPhrase="",
            l=maxPxLength,
            measure=0;
            ctx.font = "16px sans-serif";
            for (var i=0;i<wa.length;i++) {
                var w=wa[i];
                measure=ctx.measureText(lastPhrase+w).width;
                if (measure<l) {
                    lastPhrase+=(" "+w);
                }else {
                    phraseArray.push(lastPhrase);
                    lastPhrase=w;
                }
                if (i===wa.length-1) {
                    phraseArray.push(lastPhrase);
                    break;
                }
            }
            return phraseArray;
        }
    </script>
    <script src="js/text.js"></script>
    <script src="js/js.js"></script>
</body>

1 个答案:

答案 0 :(得分:2)

原因是每次都设置画布大小。当发生这种情况时:

  

当用户代理将位图尺寸设置为宽度和高度时,   它必须执行以下步骤:

     

...
    3.将划痕位图的大小调整为新的宽度和高度,然后将其清除为完全透明的黑色

Source

所以首先要做的是在canvas元素中预设元素标签(如下所示)或代码中的父作用域:

<div id="main">
    <canvas id="c" width=500 height=300></canvas>   <!-- any size you want -->
</div>

然后从JavaScript中删除这些行:

    function saveTextFromArea(y,x){
        ...snipped for example...
        var canvas = document.getElementById('c');
        var ctx = canvas.getContext('2d');
        var cw = canvas.clientWidth;
        var ch = canvas.clientHeight;
        //canvas.width = cw;             // remove this line
        //canvas.height = ch;            // remove this line

        ...snipped for example...