JSFiddle - React, Tailwind, and code Playground

HTML

<input type="file" id="images" multiple/>
	<pre id="output"></pre>

JavaScript

var IMAGE_UPLOAD_MAX_WIDTH = 1024;
	var IMAGE_UPLOAD_MAX_HEIGHT = 768;
	
//	window.onload = function() {
		var input = document.getElementById('images');
		var output = document.getElementById('output');
		input.addEventListener('change', function(e) {
			// create an array of files containing only images
			var files = Array.prototype.slice.call(input.files);
			var images = files.filter(function(file) {
				return file.type.match(/image.*/);
			});
			
			// load images
			images.forEach(function(image, index) {
				var img = image.element = new Image();
				img.onload = onImageLoad.bind(image, images);
				img.src = URL.createObjectURL(image);
			});
		});
//	};
	
	// wait for all images to load before creating the sprite
	function onImageLoad(images) {
		this.is_loaded = true;
		if (images.every(function(image){ return image.is_loaded; })) {
			var json = JSON.stringify(createSprite(images), null, 2);
			output.innerHTML = json.replace(/"sprite": "([^"]*)"/, '"sprite": "<a href="$1" target="_blank">$1</a>"')
		}
	}
	
	function createSprite(images) {
		// use a bin packing library to pack all images efficiently into a sprite
		var packer = new GrowingPacker();
		// map images into blocks for the packer, sort them by max(width, height)
		var blocks = images.map(imageBlock).sort(function(a, b) {
			var a_max = Math.max(a.w, a.h);
			var b_max = Math.max(b.w, b.h);
			return a_max < b_max ? 1 : a_max > b_max ? -1 : 0;
		});
		
		packer.fit(blocks);
		
		var canvas = document.createElement('canvas');
		var context = canvas.getContext('2d');	

		// set canvas dimensions according to the packer's data
		canvas.width = packer.root.w;
		canvas.height = packer.root.h;	

		// draw images to canvas using the blocks packing data
		blocks.forEach(function(block) {
			context.drawImage(block.el, block.fit.x, block.fit.y, block.w, block.h); 
		});
		
		// return a data uri of the sprite image
		return {
			sprite: canvas.toDataURL(),
			metadata: blocks.map(function(block)...