Last active
January 16, 2017 11:30
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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