Skip to content

Instantly share code, notes, and snippets.

@fatso83
Last active January 16, 2017 11:30
Show Gist options
  • Save fatso83/705f099ffe8720e13ff8252cebe6d733 to your computer and use it in GitHub Desktop.
Save fatso83/705f099ffe8720e13ff8252cebe6d733 to your computer and use it in GitHub Desktop.
A spinning slot machine effect, with an overlay at the end that might correspond to the result.
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<style>
*{
box-sizing: border-box;
}
body {
overflow: hidden;
}
.box{
width: 100px;
height:100px;
text-align:center;
line-height: 100px;
font-size: 40px;
font-family: Arial;
user-select: none;
border: 1px solid green;
position: relative;
translate3d(0,0,0);
}
.even {
background-color: white;
}
.odd{
color:white;
background-color: black;
}
#container {
padding: 0 aut
}
#container{
margin: 150px auto;
width: 300px;
overflow: hidden;
}
#overlayed {
position: relative;
top:-250px;
left:0;
z-index: 1;
width: 300px;
height: 250px;
background-color: red;
translate3d(0,0,0);
}
#stage{
position: relative;
top:-250px;
left:0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
overflow: hidden;
width: 300px;
height: 250px;
background-color: gray;
}
</style>
<div id="container">
<div id="overlayed"></div>
<div id="stage">
<div class="box odd ">1</div>
<div class="box even">2</div>
<div class="box odd ">3</div>
<div class="box even">4</div>
<div class="box odd ">1</div>
<div class="box even">2</div>
<div class="box odd ">3</div>
<!--<div class="box even">4</div>-->
</div>
</div>
<script>
var stage = document.querySelectorAll("#stage")[0];
var boxes = stage.querySelectorAll(".box");
var boxHeight = 100;
var stageBoxHeight = Math.ceil(250/boxHeight) // = 3 (whole or parts of) boxes
var totalHeighOfAllBoxes = boxes.length * boxHeight;
var overlay = document.getElementById("overlayed");
// center align the second box and let the other two overlap
boxMod( function(box){
var shiftNeedToAlignWithBottom = (totalHeighOfAllBoxes/2 - stageBoxHeight / 2);
var offsetToCenterMiddleBox = boxHeight - (stageBoxHeight - boxHeight)/2;
box.style.bottom = shiftNeedToAlignWithBottom - offsetToCenterMiddleBox;
});
window.onload = function() {
var startY = 0;
appendStyleRule( createNamedKeyFrame("move-down-400", startY, startY+400) );
appendStyleRule( createNamedKeyFrame("move-down-250", startY, startY+250) );
appendStyleRule( createAnimationRules(2, 6) );
document.onclick = function(e){
e.preventDefault();
toggleAnim();
}
toggleAnim();
};
function toggleAnim(){
boxMod( function(box){
box.classList.toggle("spinner-anim");
overlay.classList.toggle("drop-down-anim");
});
}
function boxMod(fn){
[].map.call(boxes,fn);
}
function createAnimationRules( speedup, numberOfSpins ) {
/*
the base total time based on these number is 3.7 secs with 6 spins and no speedup
please don't change the hard-coded factors nilly-willy as they took some time
to get to match up :-)
*/
var settings = {
spinTime: 0.5 / speedup,
easeIn: 0.7 / speedup,
easeOut: 1.0 / speedup,
easeOutFunction: 'cubic-bezier(.33,.78,.55,1.21)', // gives a slight 'bounce'
numberOfSpins: numberOfSpins
};
settings.delayAnim2= settings.easeIn;
settings.delayAnim3= settings.easeIn + settings.spinTime * numberOfSpins;
var rules = '\
.spinner-anim { \n\
animation: \n\
move-down-400 {{easeIn}}s ease-in 0s, \n\
move-down-400 {{spinTime}}s linear {{delayAnim2}}s {{numberOfSpins}}, \n\
move-down-250 {{easeOut}}s {{easeOutFunction}} {{delayAnim3}}s forwards; \n\
} \n\
.drop-down-anim { \n\
animation: move-down-250 {{easeOut}}s {{easeOutFunction}} 1 {{delayAnim3}}s forwards; \n\
} \
';
var templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
var compiledTemplate = _.template(rules, templateSettings);
return compiledTemplate( settings );
}
function createNamedKeyFrame(name, startY, endY){
var keyFrame = '\
@keyframes {name} { \
from { \
transform : translateY({startY}); \
} \
\
to { \
transform: translateY({endY}); \
} \
} \
';
return keyFrame
.replace("{name}", name)
.replace("{startY}", startY + "px")
.replace("{endY}", endY + "px");
}
function appendStyleRule(rule){
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = rule;
document.getElementsByTagName('head')[0].appendChild(style);
}
function popFirstChild(){
var child = stage.children[0];
stage.removeChild(child);
return child;
}
function popFirstChild(){
var child = stage.children[0];
stage.removeChild(child);
return child;
}
function appendChild(child){
stage.appendChild(child);
}
function shiftPos(){
appendChild( popFirstChild() );
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment