JSFiddle - React, Tailwind, and code Playground

by nderscore

HTML

<canvas id="c" width="100" height="100" />

CSS

html, body, canvas { width: 100%; height: 100%; margin: 0 }

JavaScript

var plasma = {
    t: 0,
    c: document.getElementById('c').getContext('2d'),
    colors: [],
    makeColor: function(i) {
        var r = ~~(100 * (Math.sin(i/100) + 1)),    
            g = ~~(150 * (Math.cos(255-i/50) + 1)),
            b = ~~(100 * (Math.cos(255-i/75) + 1));
        return [r, g, b, 255];
    },
    patterns: [
        function(x,y,t) {
            return Math.sin(x / 80 + t / 15) / 2;
        },
        function(x,y,t) {
            return Math.sin(x / (20 + 10 * Math.cos((y + t) / 45))) * 
                   Math.cos(y / (25 + 10 * Math.sin((x - t) / 40)));
        }
    ],
    init: function() {
        this.c.width = this.c.height = 100;
        for(var i = 256; i--;)
            this.colors[i] = this.makeColor(i);
        this.mainloop = this.mainloop.bind(plasma);
        this.mainloop();
    },
    mainloop: function() {
        var numpatt = this.patterns.length,
            c = this.c,
            pixel = 0, 
            w = c.width, h = c.height,
            newData = c.createImageData(w, h);
        for(var y = 0; y < h; y++) {
            for(var x = 0; x < w; x++) {
                var val = 0;
                for(var i in this.patterns)
                    val += this.patterns[i](x, y, this.t) + 1;
                val = Math.max(Math.min(~~(255 * val / numpatt), 255), 0);
                var colorData = this.colors[val];
                for(var i in colorData)
                    newData.data[pixel++] = colorData[i];
            }
        }
        c.putImageData(newData, 0, 0);
        this.t++;  
        requestAnimationFrame(plasma.mainloop);
    }
};
plasma.init();