JSFiddle - React, Tailwind, and code Playground

by jpeter06

HTML

<canvas width="600" height="1200" id="canvasObj"></canvas>
<div class="button">Run</div>

CSS

canvas {
	border: solid 1px #333;
}

.button {
	position: absolute;
	top: 20px;
	left: 20px;
	width: 100px;
	height: 38px;
	background-color: rgba(0, 0, 0, 0.5);
	border-radius: 5px;
	cursor: pointer;
	color: #fff;
	font-size: 20px;
	line-height: 38px;
	text-align: center;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	-webkit-transition: all 0.4s;
	-o-transition: all 0.4s;
	transition: all 0.4s;
}

.button:hover {
	background-color: rgba(0, 0, 0, 0.8);
}

JavaScript

function runImg(canvas, size, fn) {
	for (var y = 0; y < canvas.height; y++) {
		for (var x = 0; x < canvas.width; x++) {
			var i = x * 4 + y * canvas.width * 4;
			var matrix = getMatrix(x, y, size);
			fn(i, matrix);
		}
	}

	function getMatrix(cx, cy, size) {
		/**
         * will generate a 2d array of size x size given center x,
         * center y, size, image width & height
         */
		if (!size) {
			return;
		}

		var matrix = [];

		for (var i = 0, y = -(size - 1) / 2; i < size; i++, y++) {
			matrix[i] = [];

			for (var j = 0, x = -(size - 1) / 2; j < size; j++, x++) {
				matrix[i][j] = (cx + x) * 4 + (cy + y) * canvas.width * 4;
			}
		}

		return matrix;
	}
}

function getRGBA(start, imgData) {
	return {
		r: imgData.data[start],
		g: imgData.data[start + 1],
		b: imgData.data[start + 2],
		a: imgData.data[start + 3]
	};
}

function getPixel(i, imgData) {
	if (i < 0 || i > imgData.data.length - 4) {
		return {
			r: 255,
			g: 255,
			b: 255,
			a: 255
		};
	} else {
		return getRGBA(i, imgData);
	}
}

function setPixel(i, val, imgData) {
	imgData.data[i] = typeof val === 'number' ? val : val.r;
	imgData.data[i + 1] = typeof val === 'number' ? val : val.g;
	imgData.data[i + 2] = typeof val === 'number' ? val : val.b;
}

function calculateGray(pixel) {
	return ((0.3 * pixel.r) + (0.59 * pixel.g) + (0.11 * pixel.b));
}

function grayscale(canvas) {
	var ctx = canvas.getContext('2d');

	var imgDataCopy = ctx.getImageData(0, 0, canvas.width, canvas.height / 2);
	var grayLevel;

	runImg(canvas, null, function (current) {
		grayLevel = calculateGray(getPixel(current, imgDataCopy));
		setPixel(current, grayLevel, imgDataCopy);
	});

	ctx.putImageData(imgDataCopy, 0, 600);
}

function sumArr(arr) {
	var result = 0;

	arr.map(function(element, index) {
		result += (/^\s*function Array/.test(String(element.constructor))) ? sumArr(element) : element;
	});

	return result;
}

function generateKernel(sigma, size) {
	var kernel = [];

	/** Euler's number...