Как создать текстовое поле динамического рисования в html canvas

У меня нет идеи, как реализовать динамическое поле рисования для текста.

В основном вот пример вывода:

введите здесь описание изображения

Примечание:

Коробка должна быть впереди, если на холсте есть другой объект.

Обновить

Вот мой код:

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

И пример вывода с объяснением:введите здесь описание изображения

Проблема в том, как я могу сделать первый прямоугольник мыши и текст обернутым с помощью Input.style


person Believer    schedule 18.11.2015    source источник
comment
Вы хотите отобразить текст в прямоугольнике или хотите ввести текст?   -  person markE    schedule 18.11.2015
comment
@markE пользователь должен вводить текст в динамический прямоугольник, и он также может отображаться в прямоугольнике   -  person Believer    schedule 18.11.2015
comment
Я согласен с @markE, это не блестящая идея, но был вопрос с решением почти такой же проблемы: stackoverflow.com /q/29504481/3702797   -  person Kaiido    schedule 18.11.2015
comment
@Кайидо. да, варианты этого вопроса часто задают. Вы связались с ответом, который красиво рисует обернутый текст на холсте на основе ввода из input-type=text. В этом вопросе OP, похоже, также хочет, чтобы элемент ввода располагался на холсте во время ввода данных. Если бы я не устал (здесь 1:30), я бы отредактировал свой ответ ниже, чтобы разместить ввод на холсте, а затем нарисовать обернутый текст после того, как пользователь закончит печатать. Здоровья и спокойной ночи!   -  person markE    schedule 18.11.2015
comment
@markE, скрытый ввод был бы возможен со связанным ответом, но я тоже не буду делать для OP :-) Проголосовал и спокойной ночи!   -  person Kaiido    schedule 18.11.2015
comment
что такое ОП? если вы не возражаете. ха-ха   -  person Believer    schedule 18.11.2015
comment
получить его, я постараюсь сделать и понять это. Я буду публиковать обновления относительно моего решения, если я застряну. Спасибо :)   -  person Believer    schedule 18.11.2015
comment
@newuser1. Привет! ОП означает оригинальный постер. Это вовсе не отрицательное слово — это просто краткое обозначение спрашивающего. :-)   -  person markE    schedule 18.11.2015
comment
OP, похоже, также хочет, чтобы элемент ввода располагался на холсте во время ввода данных, а также размещал ввод на холсте, а затем рисовал обернутый текст после того, как пользователь закончил печатать. являются точной спецификацией, которую я ищу.   -  person Believer    schedule 19.11.2015
comment
@markE Мне интересно, ничего страшного, если ты поможешь мне с моей проблемой. Я забыл сказать, что область прямоугольника также может быть перемещена, что означает, что input-type = text невозможен, я думаю. Я думаю просто перерисовать прямоугольник и текст, когда вы перемещаете (X1, Y1) или одну точку. Кстати перетаскивание одной точки уже работает.   -  person Believer    schedule 19.11.2015
comment
Я пришел на этот сайт goldfirestudios.com/blog/108/ а можно ли с его помощью сделать динамический бокс?   -  person Believer    schedule 19.11.2015


Ответы (1)


Холст Html5 не имеет встроенной возможности ввода текста.

ИМО, не пытайтесь заставить холст делать то, для чего он не предназначен.

Вместо этого используйте CSS, чтобы расположить input-type=text над нужной частью холста. Пользователь может ввести свой текст в этот ввод.

Когда пользователь ввел желаемый текст, вы можете нарисовать его текст в прямоугольнике на холсте следующим образом:

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>

person markE    schedule 18.11.2015
comment
что вы подразумеваете под CSS для размещения input-type=text? - person Believer; 18.11.2015
comment
Изучите позиционирование CSS — в частности относительное и абсолютное позиционирование: developer.mozilla. org/en-US/docs/Web/CSS/position. Оберните свой холст в элемент div с div, имеющим position:relative. Установите холст на position:absolute. Создайте текст ввода-типа, который изначально скрыт и имеет position:absolute, и поместите его внутри обертывающего div под холстом. При необходимости используйте CSS, чтобы расположить ввод на желаемом холсте x, y и сделать его видимым. - person markE; 18.11.2015
comment
Вот пример размещения input-type=text на холсте: jsfiddle.net/m1erickson/ 9f2ct - person markE; 18.11.2015
comment
Спасибо, я постараюсь исправить ошибку, когда пользователь вводит слишком длинное слово, потому что оно просто продолжается в одной строке. - person Believer; 18.11.2015
comment
Какую ошибку вы находите? Для вашего полного решения вам нужно будет объединить входной код в моей ссылке на комментарий с отображаемым кодом обернутого текста в моем ответе. Если вы хотите предоставить пользователю большую область ввода, вы можете заменить элемент ввода на элемент textarea. - person markE; 18.11.2015
comment
например, пользовательский ввод 11111111111111111111111111111111111111, текст будет продолжаться в одну строку. Продолжение должно быть на следующей строке, если текст превышает максимальное количество символов в одной строке. - person Believer; 18.11.2015
comment
Да, закомментированный jsFiddle показывает только, как расположить ввод на холсте. Затем вы должны объединить это с кодом в моем ответе, который рисует обернутый текст на холсте. Там нет ошибки... вам просто нужно соединить 2 фрагмента кода. ;-) - person markE; 18.11.2015
comment
Я попытаюсь объединить ваш ответ со stackoverflow.com/q/29504481/3702797. - person Believer; 18.11.2015