JSFiddle - React, Tailwind, and code Playground
by levchenko_d
HTML
<div class="vertical flip-container shuffle-parent" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front shuffle" data-shuffle-value="1">
0<!-- front content -->
</div>
<div class="back shuffle" data-shuffle-value="1">
0<!-- back content -->
</div>
</div>
</div>
<div class="vertical flip-container shuffle-parent" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front shuffle" data-shuffle-value="9">
0<!-- front content -->
</div>
<div class="back shuffle" data-shuffle-value="9">
0<!-- back content -->
</div>
</div>
</div>
<div class="vertical flip-container shuffle-parent" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front shuffle" data-shuffle-value="9">
0<!-- front content -->
</div>
<div class="back shuffle" data-shuffle-value="9">
0<!-- back content -->
</div>
</div>
</div>
<div class="vertical flip-container shuffle-parent" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front shuffle" data-shuffle-value="1">
0<!-- front content -->
</div>
<div class="back shuffle" data-shuffle-value="1">
0<!-- back content -->
</div>
</div>
</div>
<br>
<button onclick="Flip()">Flip</button>
CSS
/* entire container, keeps perspective */
.flip-container {
perspective: 1000px;
display: inline-block;
}
.flip-container, .front, .back {
width: 20px;
height: 30px;
}
/* flip speed goes here */
.flipper {
/*transition: 0.6s;*/
transition-timing-function: linear;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
text-align: center;
line-height: 30px;
background: #2d3f4e;
color: #f6df42;
border-radius: 3px;
}
/* front pane, placed above back */
.front {
z-index: 2;
/* for firefox 31 */
transform: rotateY(0deg);
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
}
.vertical.flip-container {
position: relative;
}
.vertical .back {
transform: rotateX(180deg);
}
.vertical.flip-container.animate .flipper {
transform-origin: 100% 15px; /* half of height */
animation: 1s flip;
animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@keyframes flip {
0% {
transform: rotateX(180deg);
}
100% {
transform: rotateX(-720deg);
}
}
JavaScript
/*
options = {
el: //DOM
endValue: //String
duration: //MS
interval: //MS
}
*/
function Shuffle(o){//options
var range = [0,1,2,3,4,5,6,7,8,9],
rangeSize = range.length,
Interval = null,
Time = 0;
function applyRandom(){
var rand = Math.round(Math.random() * (rangeSize-1 || 1));
o.el.innerText = range[rand];
}
function applyEndValue(){
o.el.innerText = o.endValue || '?';
}
Interval = setInterval(function(){
if(Time === (o.duration || 1000)){
applyEndValue();
clearInterval(Interval);
} else {
applyRandom();
Time += (o.interval || 50);
}
}, o.interval || 50);
};
function loopIn(els, fn, int){
var interval = null,
id = 0,
duration = els.length*int,
passed = 0
interval = setInterval(function(){
if(passed != duration){
fn(els[id]);
id++;
passed+=int;
} else {
clearInterval(interval);
}
}, int)
}
function Flip(){
var elements = document.querySelectorAll('.shuffle');
loopIn(elements, function(element){
Shuffle({
el: element,
endValue: element.getAttribute('data-shuffle-value'),
duration: 500,
interval: 100
});
}, 50);
var parents = document.querySelectorAll('.shuffle-parent');
//for(i=0; i<parents.length; i++){
//var parent =
//parents[i].className = 'vertical flip-container shuffle-parent animate';
//}
loopIn(parents, function(parent){
parent.className = 'vertical flip-container shuffle-parent animate';
}, 50);
setTimeout(function(){
for(i=0; i<parents.length; i++){
parents[i].className = 'vertical flip-container shuffle-parent';
}
}, 1000);
};
window.Flip=Flip;