2013-03-19 2 views
3

Я пытаюсь получить анимационный эффект пишущей машинки на холсте HTML5, но я действительно борюсь с Word Wrapping.HTML5 Эффект канцелярской печати Canvas с переносом слов?

Вот мой Shapes.js в Сущностью: https://gist.github.com/Jamesking56/0d7df54473085b3c5394

Там, я создал объект Text, который имеет много методов. Один из них называется typeText().

typeText() в основном запускает эффект пишущей машинки, но он продолжает падать с края, и я действительно пытаюсь найти способ фиксации обертывания слов.

Может ли кто-нибудь направить меня на лучший способ сделать это?

+1

+1 для _solution без плагинов! Стандартный JavaScript и HTML5 Canvas! _. Мне нравится это. Но ваш код плохо комментируется. Неясно, какие методы 'typeText' принимает и что такое' baseObjects' на самом деле. – ShuklaSannidhya

+0

Не могли бы вы рассказать, как вы называете 'typeText', какие параметры вы передаете? – ShuklaSannidhya

+0

'baseObjects' - это массив всех моих объектов на холсте (для целей перерисовки). 'typeText()' вызывается из объекта Text. Поэтому я бы сделал «var text = new Text();», затем вызывается 'text.typeText (baseObjects, 20);' – Jamesking56

ответ

2

Раствора я использовал примерно:

var maxWidth = 250; 
var text = 'lorem ipsum dolor et sit amet...'; 

var words = text.split(' '); 
var line = [words[0]]; //begin with a single word 

for(var i=1; i<words.length; i++){ 
    while(ctx.measureText(line.join(' ')) < maxWidth && i<words.length-1){ 
     line.push(words[i++]); 
    } 
    if(i < words.length-1) { //Loop ended because line became too wide 
     line.pop(); //Remove last word 
     i--; //Take one step back 
    } 
    //Ouput the line 
} 

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

+0

О, я вижу, вы можете рассчитать слова заранее, ТОГДА начните печатать его. Единственным недостатком является то, что я также ищу отзывчивость, и что произойдет, если пользователь изменит размер моего холста? – Jamesking56

+0

Это самое простое решение, которое я видел до сих пор, хотя я мог бы интегрировать его в свой объект Text. – Jamesking56

+0

@ Jamesking56 Вы не можете добавить эффект записи типа с помощью этого метода. – ShuklaSannidhya

-1

<canvas> не предназначен для обработки текстов. Это намного облегчает это, накладывая прозрачные элементы DOM на верхнюю часть вашего <canvas>. Это, естественно, предполагает, что вам не нужно отправлять текстовые пиксели в <canvas>. В противном случае вам нужно повторно реализовать весь материал для обработки текста в Javascript, и это своего рода изобретать колесо, потому что браузеры могут просто сделать это для нас.

Подробнее об этом, используя CSS position: absolute и position: relative.

Allowing the user to type text in a HTML5 Canvas game

Я думаю, вы должны иметь DOM элемент, который имеет весь текст с прозрачным цветом, каждое письмо, завернутые с <span>. Затем вы просто начинаете делать эти <span> s видимыми, настраивая непрозрачность. Таким образом, позиции букв не изменились.

+0

Как насчет эффекта ввода типа, который я искал? Как бы я напечатал каждую букву отдельно? – Jamesking56

+0

А как насчет отзывчивости? Мое полотно реагирует, может ли наложенный текст реагировать тоже таким образом? – Jamesking56

+0

1) Оберните каждую букву в '' 2) Я не понимаю, почему это не будет –

-1

Лично я всегда использую растровые шрифты, когда мне нужен текст в моих играх на холсте. Он имеет несколько преимуществ:

  1. Заполнение FillText на медленном огне. Растровые шрифты намного быстрее.
  2. Знаете, что ширина каждой буквы делает упаковку и выравнивание текста намного проще.

Вы по-прежнему можете выбрать цвет шрифта, используя операции компоновки корпусов и размер шрифта, динамически регулируя высоту ширины ниши.

+0

Можете ли вы показать пример того, что вы имеете в виду, и как вы будете использовать растровые шрифты? поскольку он стоит, это плохой ответ, потому что он не входит в детали, необходимые для его реализации. –

+0

Вы правы. Это должен быть комментарий. Однако этот текст не помещается в комментарии. Так я должен был не включать его?Я думаю, что это все еще очень действительная и полезная информация, что может быть обманчиво сложной задачей, которую стоит разделить. Думаю, голосование проще. – Jarrod

0

Я не мог понять, как работает ваш конструктор Text. Поэтому я написал независимую функцию (не принадлежащую ни одному объекту). Все, что вам нужно передать этой функции, это строка, позиция X и Y, высота строки и отступы. Он предполагает, что холст будет присвоен переменной canvas и 2d-контекст, назначенный переменной ctx.

var canvas, ctx; 
function typeOut(str, startX, startY, lineHeight, padding) { 
    var cursorX = startX || 0; 
    var cursorY = startY || 0; 
    var lineHeight = lineHeight || 32; 
    padding = padding || 10; 
    var i = 0; 
    $_inter = setInterval(function() { 
     var w = ctx.measureText(str.charAt(i)).width; 
     if(cursorX + w >= canvas.width - padding) { 
      cursorX = startX; 
      cursorY += lineHeight; 
     } 
     ctx.fillText(str.charAt(i), cursorX, cursorY); 
     i++; 
     cursorX += w; 
     if(i === str.length) { 
      clearInterval($_inter); 
     } 
    }, 75); 
} 

Посмотрите демо-версию here.

Советы -

Я шел через код и нашел что-то ссылка this-

function Rectangle(x,y,width,height,colour) { 
    //properties 
    this.draw = function() { //Don't assigns object methods through constructors 
     ctx.fillStyle = this.colour; 
     ctx.fillRect(this.x, this.y, this.width, this.height); 
    }; 
} 

Вы не должны добавлять методы к объекту через конструктор, поскольку он создает метод каждый раз, когда объект создается. Скорее добавьте методы прототипу объекта, таким образом, они будут созданы только один раз и будут использоваться всеми экземплярами. Like-

function Rectangle(x,y,width,height,colour) { 
    //properties 
} 
Rectangle.prototype.draw = function() { 
    ctx.fillStyle = this.colour; 
    ctx.fillRect(this.x, this.y, this.width, this.height); 
} 

Кроме того, я обнаружил, что вы создаете дополнительные переменные, указывающие на некоторые объекты. Как -

var that = this; 
var fadeIn = setInterval(function() { 
    //code 
    that.draw(); 
    //code 
}, time); 

Вы не должны создавать дополнительные ссылки на Text объекта. Используйте метод bind, так что this будет указывать на объект Text. Like-

var fadeIn = setInterval(function() { 
    //code 
    this.draw(); // <-- Check this it is `this.draw` no need for `that.draw` 
    //code 
}.bind(this), time); //bind the object 

Подробнее о bind here.

Надеюсь, что это поможет.

PS: 75 миллисекунд для каждого персонажа, который будет святым 800 символов в минуту !!!


Update - Если вы хотите, масштабируемые графики вы должны рассмотреть SVG. Холст основан на растре, тогда как SVG основан на векторе. Это означает, что SVG можно легко изменить, тогда как при изменении размера холста содержимое холста начнет пикселизоваться и будет выглядеть нечетким. Read more.

Чтобы изменить размер содержимого холста, вам необходимо перекрасить весь холст. Всякий раз, когда что-то нарисовано на холсте, браузер рисует и забывает об этом. Поэтому, если вы хотите изменить размер/положение объекта, вам нужно полностью очистить полотно и перерисовать объект. В вашем случае вам нужно будет изменить ctx.font в соответствии с размером холста, а затем обновить холст, что будет очень утомительной задачей.

+0

Единственная проблема, с которой я сталкиваюсь в вашей демонстрации, заключается в том, что мой холст изменен пользователем (он всегда соответствует ширине и ширине браузера). Что произойдет, если пользователь изменит размер холста на полпути? – Jamesking56

+0

Спасибо за советы по кодированию, меня фактически научили на уровне университета использовать 'this.draw = function() {}' для методов моего объекта. Не знаете, есть ли для них какой-то стандарт? Что касается 'that = this;' я действительно не знал '.bind()' существовал так, чтобы это было полезно. – Jamesking56

+0

@ Jamesking56 Я обновил свой ответ. – ShuklaSannidhya

Смежные вопросы