JavaScript Canvas Plasma

Example of Plasma effect in JavaScript

by Jeremy Likness

HTML

<h1>Old School: JavaScript Plasma!</h1>
<div>by <a href="http://www.twitter.com/jeremylikness" target="_blank">@JeremyLikness</a></div>
<div><a href="http://csharperimage.jeremylikness.com/" target="_blank">C#er : IMage</a></div>
<canvas id="plasma">Your browser does not support the HTML5 canvas tag.</canvas>

CSS

#plasma {
    width: 320px;
    height: 200px;
    border: 1px solid black;
}

div {
    padding: 10px;
}
}

JavaScript

(function (c) {
    var ctx = c.getContext('2d'),
        palette = [],
        sine = [],
        width = c.clientWidth,
        height = c.clientHeight,
        pos1 = 0,
        pos3 = 0,
        tpos1 = 0,
        tpos2 = 0,
        tpos3 = 0,
        tpos4 = 0;

    function toHex(num) {
        return ("00" + num.toString(16)).substr(-2);
    }

    function fillPalette(pal) {
        var i, r, g;
        for (i = 0; i < 64; i += 1) {
            r = i << 2;
            g = 255 - (r + 1);
            palette[i] = '#' + toHex(r) + toHex(g) + '00';
            g = r + 1;
            palette[i + 64] = '#ff' + toHex(g) + '00';
            r = g = 255 - ((i << 2) + 1);
            palette[i + 128] = '#' + toHex(r) + toHex(g) + '00';
            g = (i << 2) + 1;
            palette[i + 192] = '#00' + toHex(g) + '00';
        }
    }

    function createSineTable(table) {
        var i, rad;
        for (i = 0; i < 512; i += 1) {
            rad = (i * 0.703125) * 0.0174532;
            table[i] = Math.floor(Math.sin(rad) * 1024);
        }
    }

    function render(table, pal, w, h) {
        var i, j, idx, x, fin = [];
        tpos4 = 0;
        tpos3 = pos3;

        for (i = 0; i < h; i += 1) {

            tpos1 = pos1 + 5;
            tpos2 = 3;
            tpos3 &= 511;
            tpos4 &= 511;

            for (j = 0; j < w; j += 1) {
                tpos1 = tpos1 & 511;
                tpos2 = tpos2 & 511;
                x = table[tpos1] + table[tpos2] + table[tpos3] + table[tpos4];
                idx = Math.floor(128 + (x >> 4));
                fin[i * w + j] = pal[idx];
                tpos1 += 5;
                tpos2 += 3;
            }

            tpos4 += 3;
            tpos3 += 1;
        }

        pos1 += 9;
        pos3 += 8;

        return fin;
    }

    function paint(ctx, buffer, w, h) {
        var i, j;
        for (i = 0; i < h; i += 1) {
            for (j = 0; j < w; j += 1) {
                ctx.fillStyle = buffer[i * w + j];
 ...