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)...