Friday, August 30, 2013

HTML5 canvas - part 1 - draw(), update() functions, confetti animation

I've been playing around with HTML5 canvas. It's really neat. Canvas is great for making games or animations. If somebody doesn't know flash and wants to make some small simple animation it might be worth looking into. The beauty of it all is that there isn't that much to learn, especially if you know some JavaScript.

This is a pretty good tutorial set http://www.html5canvastutorials.com/tutorials/html5-canvas-tutorials-introduction/ also the w3schools is a pretty good starting point.

All tutorials seem to be putting the <script>...</script> into the body tag after the canvas tag. If instead you out that into window.onload it will make sure that everything is rendered before the script runs. So I changed the order a little bit:

<html>
    <head>
        <title>My canvas</title>
        <script type="text/javascript">
            var c;
            var ctx;

            window.onload = function() {
                c = document.getElementById("myCanvas");
                ctx = c.getContext("2d");
                // your code here
            }
        </script>
    </head>
    <body style="paddingmargin0">
        <canvas id="myCanvas" width="500" height="500" style="border: 5px solid red" tabindex="1">
        </canvas>
    </body>
</html>

One thing that seems to be worth mentioning that I didn't see in many tutorials is that it's a good idea and habit to keep your draw code separate from the code where you update variables. This is not really important when you start and do very simple things. However, as soon as the project is big enough it's just asking for trouble and headaches.

So, I make 2 functions - draw() and update().

window.onload = function() {
    c = document.getElementById("myCanvas");
    ctx = c.getContext("2d");
    // your code here
    setTimeout(draw, 20);
}
var draw = function(){
    update();
    // your code here
    setTimeout(draw20);
};
var update function(){
    
    // your code here
    
};

draw() ends up being very plain and boring - just sets colors and draws out shapes, text, or images.

update() is where all the fun stuff takes place - where all the variables get altered.

One thing to keep in mind though, is that draw() keeps calling update() every time before it draws anything. It might get weird a little bit at first but you can get used to it.

Sometimes it feels like you absolutely have to update variables in draw. When that happens just rethink the solution - there are many ways you can get somewhere - you can take a bus... or walk. And although walking might seem like unnecessary and extra work you will be better of with it in the long run. While shortcuts are nice they can get you into trouble later on if your project is big enough.

Now, a small and very simple example.
Let's have a 500x500 canvas, where circles of random color will spawn in random places within the canvas without even partly exceeding the canvas border. Also let the circle radius vary from 2px to 10px.

<html>
    <head>
        <title>Confetti</title>
        <script type="text/javascript">
            var c;
            var ctx;
            var RGB;
            var circle = { x0 , y0 , radius0 };

            var randInt = function (min, max) {
                return Math.floor(Math.random() * (max1 - min)) + min;
            };

            window.onload = function() {
                c = document.getElementById("myCanvas");
                ctx = c.getContext("2d");
                setTimeout(draw100);
            };

            var draw function(){
                update();
                ctx.fillStyle = "rgb("+ R +" , "+ G +" , "+ B +")";
                ctx.beginPath();
                ctx.arc(circle.x , circle.y , circle.radius , 0 , 2*Math.PI);
                ctx.fill();
                setTimeout(draw100);
            };

            var update function(){
                R = randInt(0,255);
                G = randInt(0,255);
                B = randInt(0,255);
                circle.x = randInt(9,489);
                circle.y = randInt(9,489);
                circle.radius = randInt(2,10);
            };

        </script>
    </head>
    <body style="paddingmargin0">
        <canvas id="myCanvas" width="500" height="500" style="border: 5px solid red" tabindex="1">
        </canvas>
    </body>
</html>

That's it. You can copy the code into your text editor (I hope you're not using Notepad :) but it will do too) and open the file in your favorite browser.

var circle = { x0 , y0 , radius0 };
You can replace that with 3 normal variables rather than doing it that way, although I personally prefer it. So instead you could have:
var x=0;
var y=0;
var radius=0;
and remove all circlefrom the code.

However later on it makes more sense to not have too many loose variables and group things up. Makes things more readable and manageable. Same way var RGB; could be replaced with 
var color = { R0 , G0 , B0 };

You can go further with this problem and for instance make circles not overlap. Or have squares instead of circles (that will actually make things easier). Or add random gradients... Just play around with it, change things, break things, fix things :) you know... have fun with it.

Next example will be more complex but still just a simple animation. But I will probably have to comment it out a little bit for it to make sense. So stay tuned!

No comments:

Post a Comment