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:  300px;
  height: 300px;    
}

JavaScript

/*
//Averaging kernel
var kernel_dims = [3, 3];
var kernel = [
       [ 1/9.0, 1/9.0, 1/9.0 ],
       [ 1/9.0, 1/9.0, 1/9.0 ],
       [ 1/9.0, 1/9.0, 1/9.0 ] ];
*/

/*
//Laplace
var kernel_dims = [3, 3];
var kernel = [
    [ -1, -1, -1 ],
    [ -1,  8, -1 ],
    [ -1, -1, -1 ] ];
*/

//Heat
var kernel_dims = [3, 3];
var kernel = [
    [ 0, 0, 0 ], 
    [ 0.1, 0.02, 0.1 ],
    [ 0.2, 0.35,  0.2 ] ];


/*
//Identity
var kernel_dims = [3, 3];
var kernel = [
    [ 0, 0, 0 ],
    [ 0, 0, 1 ],
    [ 0, 0, 0 ] ];
*/


//Coloring stuff
var color_shift = [0, 0, 0];
var color_scale = [1, 1, 1];

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

//Buffers
var field_dims = [ canvas.width, canvas.height ];
var fields = new Array(2);
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
    var cur_field = fields[current_field];
    current_field = (current_field + 1) % fields.length;
    var next_field = fields[current_field];

    // 1/2 kernel dims
    var half_kernel = [kernel_dims[0]>>1, kernel_dims[1]>>1];
        
    //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[0]; ++k) {
                for(var l=0; l<kernel_dims[1]; ++l) {                
                    
                    var u = (field_dims[0] + i + l - half_kernel[0]) % field_dims[0];
                    var v = (field_dims[1] + j + k - half_kernel[1]) % field_dims[1];
                    
                    s += kernel[l][k] * cur_field[u][v];
                }
            }
           
            //Set next value to weighted sum                
            next_field[i][j] = s;
        }
   ...