Roll 3 Jims

https://www.reddit.com/r/webdev/comments/54icci/resources_for_creating_a_picture_line_up_type/

by alexb

HTML

<canvas></canvas>

CSS

body {
  background: white;
  min-height: 100vh;
}
canvas {
  cursor: pointer;
  height: 300px;
  width: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
p {
  width: 300px;
}

Babel + JSX

// URLs to load as bitmap data
// Game will automatically adjust to no. of images
var images = [
	'https://images.ctfassets.net/zczdrsyzzo2x/7pHGRaDxTeHcc1eCvFyVmX/623e79cb9fc9f9c8e822d924287fadc1/Jim.png',
	'https://images.ctfassets.net/zczdrsyzzo2x/fPpoDsV0dYd4KMAa6wuhw/3f0d70bdfcaa367c23d8400d8bc7c409/Jimmy.png',
	'https://images.ctfassets.net/zczdrsyzzo2x/fOoK9QFQULQAbsmjjOOtO/a64a789fe23de11379fbcfa44d5b0bb7/Hanna.png',
  'https://images.ctfassets.net/zczdrsyzzo2x/poglUxDfqejrYjj7OVWdL/2e2717c853890a062cbd87f11e21d6b6/Anders.png',
];
var speed = 0.002; // Speed of row animation
var segments = 3;  // No. of vertical segments

var canvas;        // Canvas HTML element
var ctx;           // 2D context for canvas
var bitmaps;       // Array of BitmapImage data
var n;             // No. of bitmaps
var started;       // Timestamp at which the simulation started
var stopped = [];  // Timestamps at which each row is stopped

// Returns Promise of an ImageBitmap
function loadImage(src) {
	return new Promise(function(resolve, reject) {
    var img = new Image();
    img.onerror = reject;
    img.onload = function() {
    	var bmp = createImageBitmap(img);
    	resolve(bmp);
    }
    img.src = src;
  });
}

function clamp(x, min, max) {
	return Math.min(max, Math.max(min, x));
}

// Called once
function init() {
  canvas = document.querySelector('canvas');
	ctx = canvas.getContext('2d');
  started = performance.now();
  
  Promise
    .all(images.map(loadImage))
  	.then(function(bitmapImages) {
    	bitmaps = bitmapImages;
      n = bitmaps.length;
      
      canvas.addEventListener('click', e => {
        if (stopped.length >= segments) {
        	stopped = []
        } else {
        	stopped.push(performance.now())
        }
      });
    	window.requestAnimationFrame(render);
    });
}

// Called every frame
function render(delta) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
	for (var i = 0; i < n; i++) {
    // +1 to scroll right or -1 to scroll left
...