JSFiddle - React, Tailwind, and code Playground

by mikola

HTML

<script src="http://www.numericjs.com/lib/numeric-1.2.3.min.js"></script>
<canvas id="c" width="128" height="128"></canvas>
<img id="eyeball_pic" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAEV0lEQVR4Xu2ZyyquYRiGn89ethGyyWaCMsWIQ3AOMhCKgRNwDDI0oUQ2U0pkSImZbCJ7ZSL7/eZb//Ou1lrHsL77+usL/Qye977++76fVzQwMBBnZGRYc3Oz5ebmWklJib29vdnOzo7V19dbZWWlXVxc2OPjo728vFgcx1ZYWGjDw8PG6/8/gai/vz9ubGy0j48PKy4utvLy8jDV8fFxEP/r68uurq7s5+cnPNnZ2QGUoaGh/396JrBobGwszszMtOfn5yBubW1t+JR/f3/b5eWlHR0dWX5+fvjUZ2Vlmf+uf+3r6+P4EnAC0cTEROyfaBf7TxS4yJubm7a2thYcwN/39zweGhoagjP09vYmYHxGiBYWFuK0tDTb29uzpqYmKyoqso2NDTs7OwvfR1FkT09PdnBwYNfX18ElPDJSf8fpJeAEopWVlfj8/DwIXVFRYYuLi3ZychIs319eCGtqasx/5/PzM5TB9/d3297eTsD4jBAAuL+/D+JOTU0FJ3C7d+G9GHoX8Ehw4evq6qylpcXS09NtZmaG00vACUSrq6vx7e2tjY+P29bWVhjJS6C/HAAXvaOjw9bX121/fz+si21tbZbqDgkYnxGi5eXleHJyMpS+m5ubkPFe8h4eHgIAVVVVNjIyEn4eHR2119dXq66utqWlJU4vAScQDQ4Oxqenp6ED+IWPF73W1lbzWHBn6OzstO7u7gDD7Ozs34hIgZOA8Rkh6urqigsKCqy0tDTk/uHhYcj8srKycDHU3t4e3nMH2N3dDZB4CZybm+P0EnACUU9PT7gI+vN4GfS17+7uLlz4+O7vdwFu+w6KO4RvBPPz8wkYnxGi1I1enJeXFwDwxu9R4Hbvjwufk5MTHr8N9HLo/w/wS6Pp6WlOLwEnkNI7+l35eUmeAABIyv5vaAAAACJAmQEcQFn91OwAAABEgDIDOICy+kSAuPoAAABEgDgDAAAAbAHKDOAAyupTAsXVBwAAIALEGQAAAGALUGYAB1BWnxIorj4AAAARIM4AAAAAW4AyAziAsvqUQHH1AQAAiABxBgAAANgClBnAAZTVpwSKqw8AAEAEiDMAAADAFqDMAA6grD4lUFx9AAAAIkCcAQAAALYAZQZwAGX1KYHi6gMAABAB4gwAAACwBSgzgAMoq08JFFcfAACACBBnAAAAgC1AmQEcQFl9SqC4+gAAAESAOAMAAABsAcoM4ADK6lMCxdUHAAAgAsQZAAAAYAtQZgAHUFafEiiuPgAAABEgzgAAAABbgDIDOICy+pRAcfUBAACIAHEGAAAA2AKUGcABlNWnBIqrDwAAQASIMwAAAMAWoMwADqCsPiVQXH0AAAAiQJwBAAAAtgBlBnAAZfUpgeLqAwAAEAHiDAAAALAFKDOAAyirTwkUVx8AAIAIEGcAAACALUCZARxAWX1KoLj6AAAARIA4AwAAAGwBygzgAMrqUwLF1QcAACACxBkAAABgC1Bm4Be7haeQK+qcAwAAAABJRU5ErkJggg==" style="display: none;">

<img id="lena_pic"...

CSS

#c {
  width:  500px;
  height: 500px;    
}

JavaScript

var kernel_dims = [2, 3, 3];
var kernel = [
    [  [ 0.0, 0.5, 0.0 ],
       [ 0.5, 0.0, 0.5 ],
       [ 0.0, 0.5, 0   ] ],
    [  [ 0.0, 0.0, 0.0 ],
       [ 0.0,-1.0, 0.0 ],
       [ 0.0, 0.0, 0.0 ] ] ];


//Add a damping factor
for(var i=0; i<kernel_dims[0]; ++i)
    for(var j=0; j<kernel_dims[1]; ++j)
        for(var k=0; k<kernel_dims[2]; ++k) {
            kernel[i][j][k] *= 0.99;
        }



//Coloring stuff
var color_shift = [128, 128, 128];
var color_scale = [1.0, 1.0, 1.0];

//Canvas elements
var canvas = document.getElementById("c");
var ctx    = canvas.getContext("2d");

//Buffers
var field_dims = [ canvas.width, canvas.height ];
var fields = new Array(kernel_dims[0] + 1);
for(var i=0; i<fields.length; ++i) {
    fields[i] = numeric.rep(field_dims, 0.0);
}
var current_field = 0;


//Applies the kernel to the image
function apply_kernel() {
    
    //Read in fields
    current_field = (current_field + 1) % fields.length;
    var next_field = fields[current_field];

    // 1/2 kernel dims
    var half_kernel = [kernel_dims[1]>>1, kernel_dims[2]>>1];
        
    //For each time segment
    for(var t=0; t<kernel_dims[0]; ++t) {   
        var K = kernel[t];
        var cur_field = fields[(current_field - 1 - t + fields.length) % fields.length];
        
        //For every pixel in the image      
        for(var i=0; i<field_dims[0]; ++i) {
          for(var j=0; j<field_dims[1]; ++j) {        
                
                //For sum up weighted average of neighbors
                var s = 0.0;
                
                for(var k=0; k<kernel_dims[1]; ++k) {
                    for(var l=0; l<kernel_dims[2]; ++l) {                
                        
                        var u = (field_dims[0] + i + k - half_kernel[0]) % field_dims[0];
                        var v = (field_dims[1] + j + l - half_kernel[1]) % field_dims[1];
                        
                        s += K[l][k] * cur_field[u][v];
                    }
         ...