📜 ⬆️ ⬇️

Bart Chalkboard Generator

Hello.
I would like to tell you about my “Bart Chalkboard Generator”. image
I’m sure most of you know the series The Simpsons, and you remember that in almost every new screensaver Bart wrote something new on the blackboard, like, “They are laughing at me, not with me”. And on the Internet often pops up a picture with the text: "I will use google before asking dump questions". Then one day I thought, why not create a simple generator of similar images, and even on Html5, what to practice?


Training


The idea was to create a Canvas application that would render the specified text on the template and make it possible to save the result.
I started by creating a sprite in Photoshop. For a basis, I took a picture from the Internet, divided it into a board and into a bart.

The drawing scheme is as follows:


Lyrical digression


By the time I started working on this mini-project, I was familiar with js for just one day (I visited Html5 games hackaton from 2niversity.com ). I have long wanted to start learning JS, but somehow there was no idea.

Html5 & js


')
I will not publish the code completely, because there is no sense in this, the source code is available.

Well, with Html, everything is simple:
<canvas id='bart' width='500' height='310'></canvas> 

In js, I started by defining some variables.
 var canvas = document.getElementById('bart'); // canvas var ctx = canvas.getContext('2d'); //  canvas var sprite = new Image(); sprite.src = 'images/sprite.png'; //  

Next, I created the main function draw (text);
Which sets the write (text, n, marginStep) function and gives the context (ctx) the necessary parameters
 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'; 

Then the length of the text is calculated for the given parameters.
 textWidth = ctx.measureText(text).width; 

Then the board is drawn.
 ctx.drawImage(sprite, 0, 0, 500, 250, 0, 0, 500, 250); 

After that there are several scenarios. Depending on the width of the entered text, the script adjusts the font size in the optimal way and draws it in ten lines, or, if the text is quite large, draws it two lines each 5 times.
 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); } 

Next comes the output of the two-line text that I took from naxel , here , thanks to him for that.
The method consists in that the text is first broken up by words into an array of words, then glued back one word with a space and after each gluing the width of the resulting string is checked.
If the width is greater than 450 (width of the board), then this line is output to canvas without the last added word 5 times with an indent of 40. Then, the second line is simply pasted and also displayed 5 times.
 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( )      } 

Bart is drawn at the end.
  ctx.drawImage(sprite, 498, 128, 80, 180, 406, 118, 80, 180); //      

That's all, it remains to fasten the text form and a button.
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 //   }; 

Saving pictures
To save the picture, I used toDataURL ('image / png'). Just open a new window with 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); //    }; 

Conclusion


It took me about two nights and two days to do all this, I know that for a normal programmer it takes a very long time, but I just started learning js, so I am almost satisfied with myself.

Apologies and excuses.


Sorry, if the code has any errors or shortcomings. I really tried to do everything beautifully and correctly.
Sorry if something is wrong in the design of the post, again this is my first post, I tried.

Demo


You can try it here bart-gen.ru , source code there.
It does not load very quickly. hosted on my home server that goes to the Internet through a very strange router, so I have to wait.

Sources



I hope someone was interested to read this.
Thanks for attention!

Source: https://habr.com/ru/post/149606/


All Articles