I had to start somewhere

I’ve been trying to get this blog up for quite some time now but never quite knew where to start… here it is. The good old “plasma effect”:

Back in the early nineties we would spend hours and days creating these amazing effects using anything from Pascal to C++ to pure assembly, or typically a mix of previously mentioned. They could be anything from colorful to grayscales, predefined color maps, pure ascii-implementations that would run blasingly fast on a 80x25 character console, with or without precalculated sinus/cosinus (in pure assembly you wouldn’t have those nice Math.sin-functions readily available)… or that was the days.

Here I’ve reincarnated (me and) the plasma effect using HTML and javascript.

Ok, so how to make it? Well we’ll start of with an HTML-page with a Canvas-element:

<html>
    <html>
    <head>
        <script src="plasma-js.js" type="text/javascript"></script>
    </head>
    <body>
        <canvas id="canvas" width="320" height="240"></canvas>
    </body>

    <script lang="javascript">
        initPlasma();
    </script>
</html>

In addition we’ll create a plasma-js.js javascript file with some … code.

I’ll step you thgouh it. First we define our function initPlasma and grab a reference to the canvas element:

function initPlasma() {

    var c = document.getElementById("canvas");

From there we’ll get the canvas 2d-context and create a bitmat that has the same dimentions as the canvas itself (320x240):

    var ctx = c.getContext("2d");
    var bitmap = ctx.createImageData(320, 240);

We need some variable to make our plasma “move”.

    var j = 0, k = 0, l = 0;
    var f = 1000;

Now we defone a function that is called every time we want to render or update our plasma effect, we’ll call it step:

    var step = function () {

Increase our “plama moving” variables:

        j = (j + 13) % f;
        k = (k + 17) % f;
        l = (l + 19) % f;

I’m using the modulo-operator to allow our numbers to repeat every time they hit f (f was set to 1000 abit up, but could be anything). That’s just like an angle or circle, that would repeat itself everytime it passes 360 degress.

I’m also using some prime numbers to increase the numbers, that is to avoid them aligning up to often (to make the plama feel a bit more random).

Now it’s time to draw our pixels. We draw pixel by pixel by creating two loops, one outer loop that take line by line, one inner loop that take pixel by pixel on those lines:


        for (var y = 0; y < bitmap.height; y++)
            for (var x = 0; x < bitmap.width; x++) {

Now, create some weird function to create a cyclic value for our red component. Out number is a value between 0 and 255:


                var r =
                    (
                        + (128 + Math.sin(2 * Math.PI * (j + 2 * x + 2 * y) / f) * 128)
                        + (128 + Math.sin(2 * Math.PI * (-k + y) / f) * 128)
                    ) / 2;

Another weird function for our green component. You should play with these yourself:


                var g =
                    (
                        + (128 + Math.sin(2 * Math.PI * (k + x + y) / f) * 128)
                        + (128 + Math.sin(2 * Math.PI * (-j + x) / f) * 128)
                    ) / 2;

And, for our blue part of our plasma:


                var b =
                    (
                        + (128 + Math.sin(2 * Math.PI * (l + x - y) / f) * 128)
                        + (128 + Math.sin(2 * Math.PI * (-l-k  - x + y) / f) * 128)
                    ) / 2;

Now that we gor our colours, we need to put them into the bitmap. Each pixel is made up of one byte for reg, one for gree, one for blue and then the it is the alpha (transparency) byte. In our case we’re fixing that to solid opaque, 255:

                let p = (x + bitmap.width * y) * 4;

                bitmap.data[p + 0] = r;
                bitmap.data[p + 1] = g;
                bitmap.data[p + 2] = b;
                bitmap.data[p + 3] = 255;
            }

After all the pixels have been filled with colors, copy our bitmap onto the canvas:

        ctx.putImageData(bitmap, 0, 0);

The last thing to do in our step-function is to request the step-function being called again (resluting in it being looped again and again and again…):

        requestAnimationFrame(step);
    }

And then the last step in our initPlasma-function is to call the step function for the first time, forcing that loop just mentioned:

    requestAnimationFrame(step);
}

All set. That was a head first into the nineties plasma effect.

First post

This is the first post. Nothing more.