JSFiddle - React, Tailwind, and code Playground

by jcubed111

HTML

<script src="https://github.com/niklasvh/html2canvas/releases/download/0.5.0-alpha1/html2canvas.js"></script>
<div id="main">hello world</div>
<div id="next">hello world 2</div>

SCSS

#main{
	background: #f0f;
	width: 400px;
	height: 300px;
	background-image: linear-gradient(#fff, #000);
	background-image: url(https://www.arborday.org/images/hero/medium/hero-ring-of-trees-looking-up.jpg)
}

$transition: transform 1s cubic-bezier(0.300, -0.435, 0.475, 1.650);
$transition: transform 0.8s ease-in-out;

.flipperContainer{
	font-size: 0 !important;
	position: relative;
	transition: height 0.2s ease-in;
	overflow: hidden;
	
	.bg{
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: -1;
	}
	
	canvas{
		display: inline-block;
		transform: rotate3d(1,-1,0,0deg);
		transition: $transition;
		transform-origin: center center;
        backface-visibility: hidden;
		
		&.end{
			transform: rotate3d(1,-1,0,-180deg);
		}
	}
	
	img{
		display: inline-block;
		transform: rotate3d(1,-1,0,-180deg);
		transition: $transition;
		transform-origin: center center;
        backface-visibility: hidden;
		
		&.end{
			transform: rotate3d(1,-1,0,0deg);
		}
	}
}

JavaScript

function flipAway(el) {
	html2canvas(el, {
		allowTaint: true,
	}).then(c => flipAwayNext(el, c));
}

function flipAwayNext(el, rendered) {
	container = document.createElement('div');
	container.className = 'flipperContainer';
	var width = rendered.width;
	var height = rendered.height;
	container.style.width = width + 'px';
	container.style.height = height + 'px';
	
	bg = document.createElement('div');
	bg.className = "bg";
	container.append(bg);
	
	$(el).replaceWith(container);
	
	const size = 100;
	let h = height / size;
	let w = width / size;
	
	const last = w+h-2;
	const rowTime = 80; // ms
	const duration = 800; // ms
	
	cs = [];
	
	for(let y = 0; y < h; y++) {
		cs[y] = [];
		for(let x = 0; x < w; x++) {
			let can, back;
			cs[y][x] = {
				can: can = document.createElement('canvas'),
				back: back = document.createElement('img'),
			}
			
			back.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Kittyply_edit1.jpg/220px-Kittyply_edit1.jpg";
			back.style.width = size + "px";
			back.style.height = size + "px";
			
			can.width = size;
			can.height = size;
			can.getContext('2d').drawImage(rendered, x*size, y*size, size, size, 0, 0, size, size);
			can.className = '';
			
			can.style.transitionDuration = back.style.transitionDuration = duration + "ms";
			
			container.append(can);
			bg.append(back);
			
			setTimeout((c, b) => {
				c.className = b.className = 'end';
			}, (last-x-y) * rowTime, can, back);
		}
	}
	
	setTimeout(doCrash, last*rowTime + duration, container);
}

function doCrash(container) {
	container.style.height = "0px";
}

document.getElementById('main').addEventListener('click', n => flipAway(document.getElementById('main')));