Здравствуйте.
Мне бы хотелось рассказать про мой «Bart Chalkboard Generator».
Я уверен, что большинство из вас знают сериал «The Simpsons», и вы помните что почти в каждой новой заставке Барт писал на школьной доске что-то новое, типа: «They are laughing at me, not with me». А в интернете часто всплывает картинка с текстом: «I will use google before asking dump questions». И вот однажды я подумал, почему бы не создать простой генератор подобных картинок, да ещё и на Html5, что бы попрактиковаться?
Идея состояла в том что бы создать Canvas приложение которое бы отрисовывало заданный текст на шаблоне и давало возможность сохранить результат.
Я начал с создания спрайта в Фотошопе. За основу я взял картинку из интернета, разделил её на доску и на барта.

Схема отрисовки следующая:

К моменту начала работы над этим мини-проектом я был знаком с js всего один день (я побывал на «Html5 games hackaton» от 2niversity.com). Я давно хотел начать изучать JS, но как-то не находилось идеи.
Код буду публиковать не полностью, ибо нет в этом смысла, исходники доступны.
Ну с Html все просто:
В js я начал с определения некоторых переменных
Дальше я создал основную функцию draw(text);
Которая задаёт функцию write(text,n,marginStep) и присвавает контексту (ctx) необходимые параметры
Потом вычисляется длинна текста при заданных параметрах
Затем отрисовывается доск��
После этого есть несколько вариантов развития событий. В зависимости от ширины введённого тескта скрипт настраивает размер шрифта оптимальным образом и рисует его в десять строк, или же, если текст совсем большой, рисует его по две строки 5 раз.
Дальше идёт вывод двухстрочного текста который я взял у naxel, здесь, спасибо ему за это.
Способ состоит в том, что текст сначала разбивается по словам в массив words, потом склеивается обратно по одному слову с пробелом и после каждой склейки проверяется ширина получившейся строки.
Если ширина больше 450(ширина доски), то в canvas выводится эта строчка без последнего добавленного слова 5 раз с отступом 40. Далее просто доклеивается вторая строчка и так же выводится 5 раз.
В конце рисуется Барт.
Вот собственно и всё, остается прикрутить текстовую форму и кнопку.
Html
Js
Сохранение картинки
Для сохранения картинки я воспользовался toDataURL('image/png'). Просто открываю новое окно с url canvas.toDataURL('image/png')
На всё это у меня ушло примерно две ночи и два дня, знаю что для нормального программиста это очень долго, но я только начал учить js, так что я собой почти доволен.
Извините, если в коде есть какие промахи или недочёты. Я правда старался всё сделать красиво и правильно.
Извините, если что-то не так в оформление поста, опять же это мой первый пост, я старался.
Опробовать можно здесь bart-gen.ru, исходники там же.
Грузится не очень быстро т.к. размещено на моём домашнем сервере который выходит в интернет через очень странный роутер, так что придётся подождать.
Надеюсь кому-нибудь было интересно это прочитать.
Спасибо за внимание!

Мне бы хотелось рассказать про мой «Bart Chalkboard Generator».

Я уверен, что большинство из вас знают сериал «The Simpsons», и вы помните что почти в каждой новой заставке Барт писал на школьной доске что-то новое, типа: «They are laughing at me, not with me». А в интернете часто всплывает картинка с текстом: «I will use google before asking dump questions». И вот однажды я подумал, почему бы не создать простой генератор подобных картинок, да ещё и на Html5, что бы попрактиковаться?
Подготовка
Идея состояла в том что бы создать Canvas приложение которое бы отрисовывало заданный текст на шаблоне и давало возможность сохранить результат.
Я начал с создания спрайта в Фотошопе. За основу я взял картинку из интернета, разделил её на доску и на барта.

Схема отрисовки следующая:
- нарисовать доску
- нарисовать текст
- нарисовать Барта поверх текста

Лирическое отступление
К моменту начала работы над этим мини-проектом я был знаком с js всего один день (я побывал на «Html5 games hackaton» от 2niversity.com). Я давно хотел начать изучать JS, но как-то не находилось идеи.
Html5 & Js
Код буду публиковать не полностью, ибо нет в этом смысла, исходники доступны.
Ну с Html все просто:
<canvas id='bart' width='500' height='310'></canvas>
В js я начал с определения некоторых переменных
var canvas = document.getElementById('bart'); //Определяю canvas var ctx = canvas.getContext('2d'); //Определяю контехт canvas var sprite = new Image(); sprite.src = 'images/sprite.png'; //Определяю спрайт
Дальше я создал основную функцию draw(text);
Которая задаёт функцию write(text,n,marginStep) и присвавает контексту (ctx) необходимые параметры
function draw(text){ marginTop = 36; //Определяю отступ сверху line = ''; // Сбрасываю line function write(text, n, marginStep){ // Эта функция напишет text по центру доски n раз с шагом по вертикали marginStep for (var i = 0; i < n; i++) { ctx.fillText(text, 250, marginTop); marginTop += marginStep; }; }; line = ''; ctx.fillStyle = '#fff'; ctx.textAlign = 'center'; ctx.font = '18px Flow';
Потом вычисляется длинна текста при заданных параметрах
textWidth = ctx.measureText(text).width;
Затем отрисовывается доск��
ctx.drawImage(sprite, 0, 0, 500, 250, 0, 0, 500, 250);
После этого есть несколько вариантов развития событий. В зависимости от ширины введённого тескта скрипт настраивает размер шрифта оптимальным образом и рисует его в десять строк, или же, если текст совсем большой, рисует его по две строки 5 раз.
if (textWidth > 0 && textWidth <= 220){ //Вывод для 0-220 тескта (tc раз на строку) textCount = Math.floor(450/(textWidth + 5)); // Узнаю сколько раз на строке поместится фраза( ширину холста делю на ширину(фразы+пробел)) for (var tc = 0; tc < textCount; tc++){ // Формирую строку line += text + ' '; }; line = line.slice(0, -1); // Убираю пробел в конце write(line, 10, 20); //Пишу }else if(textWidth > 220 && textWidth <= 225){ //Вывод для 221-225 текста (2 раза внутри строки) ctx.font = '15px Flow'; //Уменьшаю шрифт line = text + ' ' + text; //Формирую строку write(line, 10, 20); //Пишу }else if(textWidth > 225 && textWidth <= 360 ){ //Вывод для 226-360 текста (1 раз на строку) ctx.font = '20px Flow'; //Увеличиваю шрифт if (textWidth > 445){ //Проверяю не стал ли текст шире чем нужно, если так, то уменьшаю шрифт до стандартного ctx.font = '18px Flow'; textWidth = ctx.measureText(text).width; }; write(text, 10, 20); //Пишу }else if(textWidth > 360 && textWidth <= 450 ){ //Вывод для 361-450 текста, самый простой (1 раз на строку стандартным шрифтом) write(text, 10, 20); //Соответственно сразу пишу }else if(textWidth > 450 && textWidth <= 500){ //Вывод 451-500 текста (1 раз на строку) ctx.font = '15px Flow'; //Уменьшаю шрифт write(text, 10, 20); }
Дальше идёт вывод двухстрочного текста который я взял у naxel, здесь, спасибо ему за это.
Способ состоит в том, что текст сначала разбивается по словам в массив words, потом склеивается обратно по одному слову с пробелом и после каждой склейки проверяется ширина получившейся строки.
Если ширина больше 450(ширина доски), то в canvas выводится эта строчка без последнего добавленного слова 5 раз с отступом 40. Далее просто доклеивается вторая строчка и так же выводится 5 раз.
else if(textWidth > 500 && textWidth <= 700){ //Вывод 501-700 текста 2строчный! var words = text.split(' '); //Разбиваю текст на слова и зпихиваю их в массив words var countWords = words.length; //Считаю количество слов if(countWords > 4){ for (var n = 0; n < countWords; n++) { //Этот цикл будет вращатся countWords раз и в результате отдаст на доску 1 строчку, а в line положит вторую var testLine = line + words[n] + ' '; //Создаю тестовую строку var testWidth = ctx.measureText(testLine).width;//Узнаю и проверяю её ширину if (testWidth > 450) { //Если ширина тестовой строки уже больше чем доска write(line, 5, 40); //Пишу 5 раз с шагом 40 (через строчку) начиная с 36 line = words[n] + ' '; //Сбрасываю line до последнего перебранного слова }else { line = testLine; }; }; marginTop = 56; //Устанавливаю отступ на 2 строчку write(line, 5, 40); //Пишу вторую строчку фразы 5 раз с шагом 40(через строчку) начиная со второй строки доски }
В конце рисуется Барт.
ctx.drawImage(sprite, 498, 128, 80, 180, 406, 118, 80, 180); //Рисую Барта повер всего этого безобразия
Вот собственно и всё, остается прикрутить текстовую форму и кнопку.
Html
<form name='form_1' onsubmit='return false;' id='form_1'> <input name='inputText' id='inputText' type='text' maxlength='150' autocomplete='off' autofocus placeholder='Напиши сюда что-нибудь, скорее!'> <input id='writeIt' type='button' value='Написать!'> <input id='downloadIt' type='button' class='center' value='Скачать!' > </form>
Js
document.getElementById('writeIt').onclick=function(e){draw(document.forms.form_1.elements.inputText.value)}; document.getElementById('form_1').onsubmit=function(e){ //Нажатие Enter draw(document.forms.form_1.elements.inputText.value); return false //Отменяю действие браузера };
Сохранение картинки
Для сохранения картинки я воспользовался toDataURL('image/png'). Просто открываю новое окно с url canvas.toDataURL('image/png')
document.getElementById('downloadIt').onclick=function(e){ ctx.drawImage(sprite, 9, 250, 142, 25, 17, 222, 142, 25); //Рисую копирайт window.open(canvas.toDataURL("image/png"), "Скачать Bart's Chalkoard", "resizable=no,toolbar=no,menubar=no,location=no,scrollbars=no,status=no,width=530,height=340, left=400, top=120,"); //Задаю параметры всплывающего окна. ctx.drawImage(sprite, 16, 226, 134, 18, 16, 226, 134, 18); //Затираю копирайт кусочком доски };
Заключение
На всё это у меня ушло примерно две ночи и два дня, знаю что для нормального программиста это очень долго, но я только начал учить js, так что я собой почти доволен.
Извинения и оправдания.
Извините, если в коде есть какие промахи или недочёты. Я правда старался всё сделать красиво и правильно.
Извините, если что-то не так в оформление поста, опять же это мой первый пост, я старался.
Демо
Опробовать можно здесь bart-gen.ru, исходники там же.
Источники
- habrahabr.ru/post/119772/ Canvas F.A.Q
- htmlbook.ru/html5 о Html5
- javascript.ru сайт о js
- javascript.ru/forum форум на котором мне помогал очень добрый и терпеливы человек с ником vadim5june, спасибо ему за это!
- html5canvastutorials.com отличные уроки по canvas
- Остальное по мелочи в Google
Надеюсь кому-нибудь было интересно это прочитать.
Спасибо за внимание!

