Learn how to add text to your canvas and create your own meme generator
Welcome to Chapter 7, Episode 8! In our journey through the HTML Canvas, we've drawn shapes, created paths, and experimented with colors and lines. Today, we're adding another powerful feature to our toolkit: rendering text on canvas.
Text on canvas gives you pixel-perfect control over how text appears in your drawings, games, and visualizations. And as a fun way to practice, we'll be building our very own meme generator!
Let's see how the McTweak team approaches text rendering...
[typing furiously]
YES! PERFECT! The ultimate meme generator! This will REVOLUTIONIZE how the internet makes fun of things! I'll be a GOD! A DIGITAL GOD OF CHAOS!
[coffee in hand, immediately suspicious]
Oh no. Whenever you're this excited, something is about to catch fire or get reported to the cyber police.
[spinning around dramatically]
ALLY! Just in time! Check out my MASTERPIECE! A canvas-powered meme engine that can turn ANYTHING into internet gold!
[Gestures proudly to screen where a poorly drawn cat with the text "I CAN HAZ CANVAS?" floats]
[squinting]
That's... that's just Comic Sans on a badly drawn cat.
[offended]
BADLY DRAWN? This is INTENTIONAL STYLIZATION! The kids call it "shitposting aesthetics"!
The text isn't even aligned properly. It's floating halfway off the canvas!
That's part of the ARTISTIC VISION!
[snorting]
Is that supposed to be a meme? My premium meme generator creates multi-layered ironic content with dynamically generated text that adjusts for optimal comedic timing based on a machine learning algorithm trained on 50 years of comedy.
[mockingly]
Oh sure, for just 5000 credits a month, right?
[defensive]
It's actually 7500 now. We added NFT support.
[already looking horrified]
Is someone generating MEMES?! Do you have ANY IDEA about the SECURITY IMPLICATIONS of unsanitized text input in a canvas context?! What if someone inputs MALICIOUS XSS into your caption field?! The entire INTERNET could COLLAPSE!
[rolling eyes]
It's a MEME GENERATOR, not a nuclear launch system!
That's EXACTLY what they want you to think right before they INJECT ROGUE CODE!
[sighs]
What's all the shouting about? I could hear you three cubicles away.
I made a canvas meme generator for today's lesson, but APPARENTLY it's going to either bankrupt our users or destroy the internet. Or both.
[examining the screen]
Well, there are definitely some copyright concerns with using certain meme templates. And your text handling needs work—it's cutting off at the edges.
[dramatic gasp]
Et tu, Ashley?
[peeking in nervously]
Um, I think it's a cool idea for teaching canvas text. Maybe we just need to fix the text positioning? I've been reading about fillText and the textAlign property...
[suddenly excited]
YES! That's what I need! Cody, you beautiful basic bargain-bin genius!
[unsure if complimented or insulted]
Thanks...I think?
[sighing]
I was in the middle of a particularly challenging Elden Ring boss fight when I sensed a disturbance in the code continuum. Something about... memes?
Trashy's trying to teach canvas text with a meme generator, but the implementation is... chaotic.
[approaching the screen]
Canvas text is actually perfect for meme generation. fillText, textAlign, textBaseline, font properties... all essential skills. But—
[Studies the code]
You're not measuring your text width. Canvas doesn't auto-wrap like HTML. You need to calculate string width and handle wrapping manually.
[defensive]
I WAS GOING TO ADD THAT! Eventually. Probably. Maybe.
[typing quickly]
Here. measureText() gives you width metrics. You can use that to implement wrapping. Also, adding a subtle text shadow makes your captions legible on any background.
[The meme suddenly looks much more professional]
[impressed but trying not to show it]
Well, that's... adequate. Still lacks my premium features, of course.
At least sanitize the input!
[beaming]
It's... it's BEAUTIFUL! The kids are going to LOVE this! They can make memes AND learn canvas text properties! It's EDUCATIONAL CHAOS!
[excited bark]
Woof! Funny pictures! Snowzie want meme too!
[with rare smile]
Canvas text isn't just for memes. It's for any situation where you need precise control over text rendering. Games, data visualization, dynamic graphics...
[to audience]
Today we're going to learn how to add text to our canvas creations, including all the properties that help us control position, alignment, font, and style. And yes, we'll make some memes too—because learning should be fun!
[whispering excitedly to students]
And after class, I'll show you how to make text that EXPLODES when you click it!
[overhearing]
I KNEW IT!
Drawing text on a canvas is done primarily with two methods: fillText() and strokeText(). These allow you to render solid or outlined text, respectively.
// Get the canvas context const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // Set text properties ctx.font = '30px Arial'; ctx.fillStyle = '#FF71CE'; // Neon pink // Draw filled text ctx.fillText('Hello Canvas!', 50, 50); // Draw outlined text ctx.strokeStyle = '#01FFAA'; // Neon green ctx.lineWidth = 1; ctx.strokeText('Outlined Text', 50, 100);
💡 Pro Tip:
You can combine fillText() and strokeText() on the same text to create outlined text with a fill color!
Canvas provides several properties to control how text is aligned and positioned:
The textAlign property controls horizontal alignment:
left: Default, aligns text to the left of the starting pointcenter: Centers text at the starting pointright: Aligns text to the right of the starting pointThe textBaseline property controls vertical alignment:
alphabetic: Default, aligns to the bottom of most letterstop: Aligns to the top of the em squaremiddle: Aligns to the middle of the em squarebottom: Aligns to the bottom of the em square// Set text alignment ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; // Now the text will be centered at the specified coordinates ctx.fillText('Centered Text', canvas.width / 2, canvas.height / 2);
The font property lets you control the appearance of your text. It uses the same syntax as CSS fonts:
ctx.font = 'italic bold 40px "Comic Sans MS", cursive';
The font string can include:
Canvas does not automatically wrap text or adjust for text width. To properly position or wrap text, you need to measure it first using measureText():
// Measure text width const text = 'How wide is this?'; const metrics = ctx.measureText(text); const textWidth = metrics.width; console.log(`The text is ${textWidth} pixels wide`); // Center text based on its width const x = (canvas.width - textWidth) / 2; ctx.fillText(text, x, 100);
Width: 0 pixels
Canvas allows you to add shadows and other effects to your text, making it more readable and visually interesting:
// Set text shadow (x-offset, y-offset, blur, color) ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; ctx.shadowBlur = 5; ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; // Draw text with shadow ctx.fillStyle = 'white'; ctx.fillText('Shadow Text', 100, 100); // Reset shadow for future drawing ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = 0;
⚠️ Performance Note:
Shadows can impact performance, especially on complex scenes or mobile devices. Use them sparingly and consider disabling them for performance-critical applications.
Canvas doesn't automatically wrap text like HTML. To create multi-line text, you need to measure and split it manually:
// Function to draw wrapped text function wrapText(context, text, x, y, maxWidth, lineHeight) { const words = text.split(' '); let line = ''; for(let n = 0; n < words.length; n++) { const testLine = line + words[n] + ' '; const metrics = context.measureText(testLine); const testWidth = metrics.width; if (testWidth > maxWidth && n > 0) { // Draw the line and start a new one context.fillText(line, x, y); line = words[n] + ' '; y += lineHeight; } else { line = testLine; } } // Draw the last line context.fillText(line, x, y); }
Now that we've learned about canvas text, let's put it all together to build a simple meme generator! We'll apply text to the top and bottom of an image, just like classic memes.
💡 Remember:
When using images in your projects, make sure you have the rights to use them or use openly licensed content.
🚀 Extension Challenge:
Try to add the following features to your meme generator:
fillText(text, x, y) - Draws filled textstrokeText(text, x, y) - Draws outlined textmeasureText(text) - Returns metrics about textfont - Font style, weight, size, and familytextAlign - Horizontal alignment (left, center, right)textBaseline - Vertical alignment (top, middle, bottom)direction - Text direction (ltr, rtl)⚠️ Remember:
Canvas text is not accessible to screen readers by default. For accessible applications, always provide alternative text or descriptions for important canvas content.
[tail wagging excitedly]
Memes look good! Text pretty! Snowzie approve! CODE IS COMMITTED!