1

I don't have an idea on how to implement dynamic drawing box for text.

Basically here is the sample output:

enter image description here

Note:

The box should be infront if there is another object in the canvas.

Update

Here is my code so far:

MouseDown(){
//if first mousedown
     X1 = tempX; //tempX is for current positon
     Y1 = tempY;
     if (Input.style.display === "none") {
        Input.value = "";
        Input.style.top = tempX + 'px';
        Input.style.left = tempY + 'px';
        Input.size = 1;
        Input.style.display = "block";
        Draw();
        }
}

Draw(){
    var userInput = Input.value;
    rectangledText(X1, Y1, 150, userInput, 12, 'verdana'); //code by markE
}

 function rectangledText(x, y, width, text, fontsize, fontface) { //code by markE
        self.TextWidth = ctx.measureText(Text).width;
        var height = wrapText(x, y, text, fontsize, fontface, width)

        ctx.strokeRect(x, y, width, height);

    }


    function wrapText(x, y, text, fontsize, fontface, maxwidth) {
        var startingY = y;
        var words = text.split(' ');
        var line = '';
        var space = '';
        var lineHeight = fontsize * 1.286;
        ctx.font = fontsize + "px " + fontface;
        ctx.textAlign = 'left';
        ctx.textBaseline = 'top'
        for (var n = 0; n < words.length; n++) {
            var testLine = line + space + words[n];
            space = ' ';
            if (ctx.measureText(testLine).width > maxwidth) {
                ctx.fillText(line, x, y);
                line = words[n] + ' ';
                y += lineHeight;
                space = '';
            } else {
                line = testLine;
            }
        }
        ctx.fillText(line, x, y);
        return (y + lineHeight - startingY);
    }

And sample output with explanation:enter image description here

The issue is how I can make the first mousedown rectangle and text be wrapped using the Input.style

Believer
  • 182
  • 1
  • 13
  • Are you wanting to **display text in a rectangle** or are you wanting to **input text**? – markE Nov 18 '15 at 05:02
  • @markE the user should input text in the dynamic rectangle and it can also be displayed in the rectangle – Believer Nov 18 '15 at 05:08
  • I do agree with @markE this is not a brilliant idea, but there was this question with a solution for an almost same problem : http://stackoverflow.com/q/29504481/3702797 – Kaiido Nov 18 '15 at 06:15
  • @Kaiido. yes, variations of this question are frequently asked. You've linked to an answer that nicely draws the wrapped text on canvas based on input from an input-type=text. In this question, the OP seems to also want the input element to be positioned on the canvas during data entry. If I wasn't getting tired (it's 1:30am here) I would edit my answer below to both position the input over the canvas and then draw the wrapped text after the user is done typing. Cheers and good night! – markE Nov 18 '15 at 06:28
  • @markE, an hidden input would be possible with the linked answer but I won't do for OP either :-) Upvoted and good night ! – Kaiido Nov 18 '15 at 06:30
  • what's OP ? if you don't mind. haha – Believer Nov 18 '15 at 06:32
  • get it, I'll try to do and understand it. I'll post updates regarding my solution if I get stuck. Thanks :) – Believer Nov 18 '15 at 06:38
  • @newuser1. Hey! OP means "original poster". It's not negative at all -- it's just a quick shorthand way of saying "the questioner". :-) – markE Nov 18 '15 at 17:25
  • "OP seems to also want the input element to be positioned on the canvas during data entry" and "to both position the input over the canvas and then draw the wrapped text after the user is done typing." are the exact specification that I'm looking for. – Believer Nov 18 '15 at 22:35
  • @markE I'm wondering if it's fine if you could help me with my problem. I forgot to tell that the rectangle area can also be move, meaning the input-type = text is not possible I guess. I'm thinking to just redraw the rectangle and text when you move the (X1,Y1) or the one point. Btw the dragging of one point is already working. – Believer Nov 18 '15 at 23:45
  • I came to this site http://goldfirestudios.com/blog/108/CanvasInput-HTML5-Canvas-Text-Input , is it possible to make the dynamic box with the use of it? – Believer Nov 19 '15 at 02:22

1 Answers1

3

Html5 canvas does not have any native text input capability.

IMO, don't try to make canvas do what it was not intended to do.

Instead, use CSS to position a input-type=text over the desired part of the canvas. The user can enter their text into this input.

When the user has entered their desired text you can draw their text in a rectangle on the canvas like this:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var text='Lorem ipsum dolor sit amet, vel te vocent bonorum singulis. Quem magna commune nam in. Ut eos oportere persecuti efficiantur.';

rectangledText(50,50,150,text,12,'verdana');

function rectangledText(x,y,width,text,fontsize,fontface){

  var height=wrapText(x,y,text,fontsize,fontface,width)

  ctx.strokeRect(x,y,width,height);

}


function wrapText(x,y,text,fontsize,fontface,maxwidth){
  var startingY=y;
  var words = text.split(' ');
  var line = '';
  var space='';
  var lineHeight = fontsize*1.286;
  ctx.font = fontsize + "px " + fontface;
  ctx.textAlign='left';
  ctx.textBaseline='top'
  for (var n=0; n<words.length; n++) {
    var testLine = line + space + words[n];
    space=' ';
    if (ctx.measureText(testLine).width > maxwidth) {
      ctx.fillText(line,x,y);
      line = words[n] + ' ';
      y += lineHeight;
      space='';
    } else {
      line = testLine;
    }
  }
  ctx.fillText(line, x,y);
  return(y+lineHeight-startingY);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
markE
  • 102,905
  • 11
  • 164
  • 176
  • what do you mean by CSS to position a input-type=text? – Believer Nov 18 '15 at 05:20
  • Research CSS positioning -- in particular relative and absolute positioning: https://developer.mozilla.org/en-US/docs/Web/CSS/position. Wrap your canvas in a div element with the div having `position:relative`. Set the canvas to `position:absolute`. Create an input-type-text that is initially hidden and having `position:absolute` and put it inside the wrapping div below the canvas. When needed, use CSS to position the input at desired canvas x,y and make it visible. – markE Nov 18 '15 at 05:30
  • Here's a somewhat on-point demo of positioning a input-type=text over the canvas: http://jsfiddle.net/m1erickson/9f2ct/ – markE Nov 18 '15 at 05:36
  • Thanks I will try to fix the bug when the user types too long word because it just continues in one line – Believer Nov 18 '15 at 06:11
  • Which bug are you finding? For your complete solution, you will need to combine the input code in my comment link with the display wrapped-text code in my answer. If you want to give the user a larger input area then you can substitute a textarea element for the in input element. – markE Nov 18 '15 at 06:13
  • for example the user input is "111111111111111111111111111111111111111", the text will just continue in one line. The continuation should be in the next line if the text exceeded the max character in one line – Believer Nov 18 '15 at 06:17
  • Yes, the commented jsFiddle only shows you how to position an input over the canvas. Then you must combine that with the code in my answer that draws wrapped text on the canvas. There's no bug...you just need to put the 2 pieces of code together. ;-) – markE Nov 18 '15 at 06:20
  • I will try to combine your answer with stackoverflow.com/q/29504481/3702797 – Believer Nov 18 '15 at 06:26