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')));