Abusing the Canvas Tag: Introduction and Lesson 1 – Blink blink blink

Purpose

The point of these articles will be to teach you how to use the HTML5 Canvas Tag. Although, instead of directly teaching you how to do things that are useful, I’m going to try to show that the canvas tag can be used to bring back the worst of the Bad Old Days and even set some new lows for bad design patterns.

Why do it this way? I dunno, seems like fun. Isn’t it always more fun to do something stupid than do something actually useful? I mean, how many object oriented programming books teach you the concepts referencing cars or bank accounts? Most of them, right? It’s so boring. So let’s do something dumb.

Who is this for?

I’m going to assume you have at least a little background in programming. Someone who knows how JavaScript works, and how objects work. There are a billion different places to learn that stuff, but I think if you have even the basics down you’ll be able to follow along.

That being said, if you’re a programmer you can probably just look at an API reference somewhere and that’ll be faster. So, who is this for, really? Programmers with a sense of humor, I suppose.

Lesson 1: Bring Back the Blink

Do you guys remember the blink tag? It’s from the Netscape days, and it was one of the most annoying things on the Internet. This and the marquee tag (probably lesson 2, hehehe) were cheap, simple ways for a beginning web developer to put some “motion” on their website. Also, animated gifs. Too many animated gifs.

So, the blink tag is no longer officially supported by any modern browser, and the replacement CSS text-decoration:blink is also being phased out. The reasons being that it provides poor accessibility, it’s hard to print, and it doesn’t have any real practical purpose.

So let’s bring it back.

The canvas is supported by every major browser, and we can emulate the blink tag to some extent using it. Simple, eh? It might even be worse when it comes to accessibility. No, it is worse.

So let’s start with some basic HTML. You could do some inline canvases to make it look like we’re not on a canvas, but since we’re in tutorial land, the canvas will be big and impractical.

<html>
<head>
</head>
<body>
<button onclick="startBlinking()">Start Blinking!</button>
<canvas id="canvas1" width="500px" height="500px" />
</body>
</html>

OK, simple enough. We have a 500px by 500px canvas and a button. Right now the button calls a method that does not exist, but we’re getting there.

Alright, let’s pretend for a moment that we’re loading up a canvas entirely for the purpose of making blinking text. Awful, right? Assuming that, we need to do the following:

  1. Draw the text on the canvas
  2. Wait for a while
  3. Clear the canvas
  4. Wait for a while
  5. GOTO 1

Cool, so let’s start by adding a script tag in the head section of the document, and see what it takes to get the canvas. I usually use jQuery because I’m lazy, but it seems like overkill for this little project, so I’ll be using native JS. Let’s add that startBlinking function.

<script type="text/javascript">
function startBlinking() {
    var c = document.getElementById("canvas1");
}
</script>

Awesome, that’s it. We get the canvas like we get any other object. Now, so that we can have completely unnecessary extra portability, let’s try making an object that handles the blinking. Let’s start by just having it draw the text. Simple enough, eh? To do that we need to get the 2D context we can draw on, then call the context’s “fillText” function, which draws filled in text. We would use strokeText() if we just wanted the outlines.

<script>
function Blinker()
{
    this.drawText() = function(canvas, text, xloc, yloc) {
        var context = canvas.getContext("2d");
        context.fillText(text, xloc, yloc);
    }
}
</script>

Here’s a fiddle with startBlinking() calling the drawText(): http://jsfiddle.net/kadono/m6P3d/ Obviously, it doesn’t blink yet, it just draws the text.

OK, let’s add a little OOP thinking to this Blinker object. What variables do we need? Well, obviously we need a reference to the canvas, the text to blink, and the location, but we also need to know if the text is currently visible and how fast to make it blink, right? Let’s add some stuff to the constructor and have some instance variables. We can change our drawText to use those variables in the process.

function Blinker(canvas, blinkingText, period, xloc, yloc) {
    this.textVisible = false;
    this.canvas = canvas;
    this.text = blinkingText;
    this.xloc = xloc;
    this.yloc = yloc;
    this.period = period;
    this.running = false;

    this.drawText = function() {
        var context = this.canvas.getContext("2d");
        context.fillText(this.text, this.xloc, this.yloc);
        this.textVisible = true;
    }
}

Fancy, don’t you think? We still need to make it blink though. So let’s start making a function that does the blinking. Since we’re crazy and using a canvas for nothing other than our blinking text things are simple. The function should just check to see if the text is drawn, and either clear the canvas or draw the text. Easy. To clear the canvas we’re going to use the clearRect function and just clear from (0,0) to (width, height):

this.doBlink = function() {
    if(this.textVisible) {	
        var context = this.canvas.getContext("2d");
        context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.textVisible = false;
    }
    else {
        this.drawText();
    }
}

All of this make sense? So every time that doBlink is called, it will either draw the text or clear the canvas. Now all we have to do is call doBlink every time we hit the number of milliseconds stored in the period variable. To do that we’ll just use window.setInterval(). The only issue with setInterval is that when it calls the method, it sets this to be the window. To make it not do that, we create a copy of this and pass it into the function manually.

There are a few ways of doing it, like having start() and stop() functions. This is supposed to be dumb though, so we’ll just have it happen on construct. Here’s the whole script segment:

function startBlinking()
{
    var c = document.getElementById("canvas1");
    var blinker = new Blinker(c, "Welcome to my homepage! Sign my guestbook!", 500, 20, 20);
}

function Blinker(canvas, blinkingText, period, xloc, yloc)
{
    this.textVisible = false;
    this.canvas = canvas;
    this.text = blinkingText;
    this.xloc = xloc;
    this.yloc = yloc;
    this.period = period;
    var self = this; // This is to pass the reference into setInterval
    this.interval = setInterval(function() { self.doBlink(); }, this.period);
    this.doBlink = function()
    {
        var context = this.canvas.getContext("2d");
        if(this.textVisible)
        {    
            context.clearRect(0, 0, this.canvas.width, this.canvas.height);
            this.textVisible = false;
        }
        else
        {
            this.drawText();
        }
    };
    this.drawText = function()
    {
        var context = this.canvas.getContext("2d");
        context.fillText(this.text, this.xloc, this.yloc);
        this.textVisible = true;
    };
}

And here’s a fiddle to the final, working product: http://jsfiddle.net/kadono/ZLCn3/

Conclusion

Well, we made blinking text. There are quite a few other things we could do, like changing the font face, color, size, and so on. We’ll get there, don’t worry. One step at a time, just going in and changing the color wouldn’t really be abusing the canvas tag, would it? Next time, we’ll start messing around with animating our text. Marquee? Of course. Other stupid stuff? Who knows?

Table of Contents

  1. Introduction and Recreating the Blink Tag [this post]

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *