<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="machine">
<div class="container">
<div class="winner">
</div>
</div>
<div class="handle">
</div>
</div>
<style scope id="setting"></style>
<style scope id="update"></style>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
*{
padding : 0;
margin: 0;
box-sizing: border-box;
}
.machine{
display: inline-block;
position: relative;
opacity: 0;
}
.container{
width : 1200px;
height : 400px;
border-style : solid;
border-color : hsl(0,10%,50%) hsl(0,20%,50%) hsl(0,10%,50%) hsl(0,20%,50%);
border-width : 15px;
display : flex;
background: linear-gradient(to bottom, #696992 0%, #afb0b7 20%, #e9e9e9 35%, #8f9e90 69%, #e7e7e7 100%);
box-shadow: inset 0 0 50px #000000;
position: relative;
overflow: hidden;
float: left;
background-clip: content-box;
}
.container:before{
content: '';
position: absolute;
width: calc(100% - 40px);
top : calc(50% - 20px);
left: 0;
border-style: solid;
border-width: 20px 20px;
border-color: transparent hsla(0,70%,50%,0.75) transparent hsla(0,70%,50%,0.75);
height : 2px;
background-color: rgba(250,250,250,0.5);
overflow: hidden;
z-index: 1;
background-clip: content-box;
}
.container:after{
content: '';
position: absolute;
width: 100%;
height: 100%;
background : linear-gradient(to bottom, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0) 80%,rgba(0,0,0,0.8) 100%);
}
.col{
width: 100%;
//transition: transform 0.2s linear;
}
.row{
border-style: solid;
border-color : #eee;
border-width: 2px;
//border-radius : 50%;
}
.row:after{
content: '';
display: block;
padding-top: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.seven:after {background-image : url("./seven.svg");}
.lemon:after {background-image : url("./lemon.svg");}
.cherry:after {background-image : url("./cherry.svg");}
.watermelon:after {background-image : url("./waterMelon.svg");}
.banana:after {background-image : url("./banana.svg");}
.bar:after {background-image : url("./bar.svg");}
.prune:after {background-image : url("./prune.svg");}
.bigwin:after {background-image : url("./bigwin.svg");}
.orange:after {background-image : url("./orange.svg");}
.seven:after {background-image : url(//bannerflow.blob.core.windows.net/resources/seven-6803e6a7-66bb-475d-b201-e2551ac41f77.svg?v=636058905940602803);}
.lemon:after {background-image : url(//bannerflow.blob.core.windows.net/resources/lemon-427191a8-0a28-43fb-8bf9-6a68df0d8d0d.svg?v=636058905940602803);}
.cherry:after {background-image : url(//bannerflow.blob.core.windows.net/resources/cherry-73d79a68-bece-46b2-9f93-fcc4617b6dbc.svg?v=636058905940602803);}
.watermelon:after {background-image : url(//bannerflow.blob.core.windows.net/resources/watermelon-53668bfb-8cd0-4107-b9be-b2379984b9fb.svg?v=636058905940602803);}
.banana:after {background-image: url(//bannerflow.blob.core.windows.net/resources/banana-a70ac7d5-feda-4c4a-80bc-1fefc5cf1f9f.svg?v=636058905940602803);}
.bar:after {background-image : url(//bannerflow.blob.core.windows.net/resources/bar-69414337-7bd5-4fa0-9dfd-3f73eb313a4d.svg?v=636058905940602803);}
.prune:after {background-image : url(//bannerflow.blob.core.windows.net/resources/prune-eb66576f-c6ba-4c4a-88c6-b659ce01f771.svg?v=636058905940602803);}
.bigwin:after {background-image : url(//bannerflow.blob.core.windows.net/resources/bigwin-ea7b5813-de4b-40c6-b708-e992f57be3e0.svg?v=636058905940602803);}
.orange:after {background-image : url(//bannerflow.blob.core.windows.net/resources/orange-625c9be2-9b9e-45aa-b574-808930b71c41.svg?v=636058905940602803);}
/*-------------=== winner style ===-------------*/
.winner{
background-color: transparent;
-webkit-transition: transform 0.1s linear,background-color 0.1s ease;
-moz-transition: transform 0.1s linear,background-color 0.1s ease;
-o-transition: transform 0.1s linear,background-color 0.1s ease;
transition: transform 0.1s linear,background-color 0.1s ease;
-webkit-transform: scale(0);
-moz-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
pointer-events: none;
}
.winner.active{
-webkit-transition: transform 0.1s linear,background-color 0.5s ease;
-moz-transition: transform 0.1s linear,background-color 0.5s ease;
-o-transition: transform 0.1s linear,background-color 0.5s ease;
transition: transform 0.1s linear,background-color 0.5s ease;
background-color: rgba(0,0,0,0.5);
-webkit-transform: scale(1);
-moz-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
.winner,.winner:before,.winner:after{
position: absolute;
top: 0;
left :0;
width: 100%;
height: 100%;
content: '';
display: block;
z-index: 3;
}
.winner:before,.winner:after{
width: 100vw;
height: 100vw;
top : -25vw;
}
.winner:before{
background : url(//bannerflow.blob.core.windows.net/resources/winner2-d4e9ae90-43f8-4575-99b9-fc675462bc35.svg?v=636058905940602803) no-repeat center;
background-size: cover;
-webkit-animation: rotateBackground 12s linear infinite;
-moz-animation: rotateBackground 12s linear infinite;
-o-animation: rotateBackground 12s linear infinite;
animation: rotateBackground 12s linear infinite;
}
.winner:after{
background : url(//bannerflow.blob.core.windows.net/resources/winner1-e3971196-c01b-4985-8303-3a1829f2d529.svg?v=636058905940602803) no-repeat center;
background-size: 50% 50%;
-webkit-animation: scaleForeground 2s linear infinite;
-moz-animation: scaleForeground 2s linear infinite;
-o-animation: scaleForeground 2s linear infinite;
animation: scaleForeground 2s linear infinite;
}
@-webkit-keyframes rotateBackground {
100% { -webkit-transform: rotate(360deg); }
}
@-moz-keyframes rotateBackground {
100% { -moz-transform: rotate(360deg); }
}
@-o-keyframes rotateBackground {
100% { -o-transform: rotate(360deg); }
}
@keyframes rotateBackground {
100% { transform: rotate(360deg); }
}
@-webkit-keyframes scaleForeground {
50% { -webkit-transform: scale(0.5); }
}
@-moz-keyframes scaleForeground {
50% { -moz-transform: scale(0.5); }
}
@-o-keyframes scaleForeground {
50% { -o-transform: scale(0.5); }
}
@keyframes scaleForeground {
50% { transform: scale(0.5); }
}
/*-----------------------------------------------*/
.handle{
position: relative;
float: left;
vertical-align: top;
height : 60px;
margin-top : 70px;
width : 15px;
border-radius: 0 5px 5px 0/20px;
border : 1px solid rgba(189, 160, 112, 0.5);
background : linear-gradient(to bottom, #CD9819 0%,#f5f5f5 20%,#e2ba78 67%, #b6783d 90%, #CD9819 100%);
}
.handle,.handle:before,.handle:after{
transition: all 0.2s linear;
cursor: pointer;
}
.handle:before,.handle:after{
content: '';
display: block;
position: absolute;
}
.handle:before{
border-style: solid;
border-width: 1px;
border-color: rgba(163,126,67,0.1);
background: linear-gradient(to right, #f5d6b1 0%, #cc9310 20%,#f1e767 60%,#f5f5f5 90%,#f1e767 100%);
width: 8px;
height: 80px;
bottom: 30px;
right: -10px;
border-bottom-right-radius: 10px 8px;
}
.handle:after{
width: 22px;
height: 22px;
border-radius: 50%;
top: -64px;
right: -17px;
border: 1px solid rgba(204,147,16,0.3);
background: radial-gradient(ellipse at 75% 25%, #ffffff 0%,#f1e767 25%,#cc9310 60%,#feb645 91%);
}
.handle.active{
background-position:0 47px;
}
.handle.active:before{
height: 0px;
border-bottom-right-radius: 2px;
transform: translateY(5px);
}
.handle.active:after{
transform: translateY(85px);
}
var fps = 60;
window.raf = (function(){
return requestAnimationFrame || webkitRequestAnimationFrame || mozRequestAnimationFrame || function(c){setTimeout(c,1000/fps);};
})();
/*--------------=== Slot machine definition ===--------------*/
(function() {
var NAME = "SlotMachine",
defaultSettings = {
width : "600",
height : "600",
colNum : 3,
rowNum : 9,
winRate : 50,
autoPlay : true,
autoSize : false,
autoPlayTime : 10,
layout : 'compact',
handleShow : true,
handleWidth : 35,
handleHeight : 30,
machineBorder : 15,
machineColor : 'rgba(120,60,30,1)',
names : [
"seven",
"lemon",
"cherry",
"watermelon",
"banana",
"bar",
"prune",
"bigwin",
"orange"
]
},
completed = true,
isShuffle = true,
supportTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints,
firstTime = true,
nextLoop = null ;
SlotMachine = function (argument) {
this.init = this.init.bind(this);
this.run = this.run.bind(this);
this.addListener = this.addListener.bind(this);
this.beforeRun = this.beforeRun.bind(this);
this.afterRun = this.afterRun.bind(this);
this.showWin = this.showWin.bind(this);
this.rotateHandle = this.rotateHandle.bind(this);
this.colArr = [];
this.options = {};
}
SlotMachine.prototype.beforeRun = function(){
if (completed) {
this.showWin(false);
completed = false;
var result = null;
result = this.options.names[random(this.options.rowNum*100/this.options.winRate)|0];//set winrate
for(var i=0;i<this.options.colNum;i++){
this.colArr[i].beforeRun(result);
}
this.rotateHandle();
this.run();
}
if (this.options.autoPlay) nextLoop = setTimeout(function(){this.beforeRun()}.bind(this),this.options.autoPlayTime*1000);
}
SlotMachine.prototype.afterRun = function(){
completed = true;
var results = [],win=true;
for(var i=0;i<this.options.colNum;i++){
results.push(this.colArr[i].getResult());
if (i>0 && results[i]!=results[i-1]) {
win = false;
break;
}
}
if(win){
this.showWin(true);
setTimeout(function(){
this.showWin(false);
}.bind(this),this.options.autoPlayTime*1000);
}
}
SlotMachine.prototype.rotateHandle = function(){
var handle = document.querySelector(".handle");
if (handle) {
handle.addClass("active");
setTimeout(function(){
handle.removeClass("active");
},1000);
}
}
SlotMachine.prototype.run = function(){
var done = true;
for(var i=0;i<this.options.colNum;i++){
done &= this.colArr[i].run();
}
if (!done) raf(this.run)
else this.afterRun();
}
SlotMachine.prototype.showWin = function(show){
var winner = document.querySelector(".winner");
if (winner) winner.className= show ? "winner active" : "winner";
}
SlotMachine.prototype.init = function(){
//reset all
completed = true;
clearTimeout(nextLoop);
//get settings
var BannerFlow = arguments[0],
settingStyle = "",
machine = document.querySelector(".machine"),
container = document.querySelector(".container");
machine.style.opacity = 0;
for(var key in defaultSettings) {
this.options[key] = defaultSettings[key];
}
if (BannerFlow!==undefined){
var settings = BannerFlow.settings;
this.options.winRate = settings.winRate ? settings.winRate : defaultSettings.winRate;
this.options.autoPlay = settings.autoPlay;
this.options.colNum = settings.numberColumn ? settings.numberColumn : defaultSettings.colNum;
this.options.layout = settings.layout ? settings.layout : defaultSettings.layout;
this.options.machineColor = settings.machineColor ? settings.machineColor : defaultSettings.machineColor;
this.options.machineBorder = settings.machineBorder>=0 ? settings.machineBorder : defaultSettings.machineBorder;
this.options.height = settings.height ? settings.height : defaultSettings.height;
this.options.width = settings.width ? settings.width : defaultSettings.width;
this.options.autoSize = settings.autoSize;
if (this.options.autoSize) {
this.options.height = window.innerHeight;
this.options.width = window.innerWidth;
}
this.options.handleShow = settings.handleShow;
this.options.handleWidth = this.options.handleShow ? defaultSettings.handleWidth : 0;
this.options.autoPlayTime = settings.autoPlayTime ? settings.autoPlayTime : defaultSettings.autoPlayTime;
this.options.customImage = settings.customImage;
}
//apply settings
if (this.options.customImage){
var urls = BannerFlow.text.strip().split(",");
this.options.names = [];
for(var i=0;i<urls.length;i++){
var name = "image-"+i ; urls[i];
this.options.names.push(name);
settingStyle += getStyle("."+name+":after",{
"background-image" : "url('"+urls[i]+"')"
});
}
}
settingStyle += getStyle(".machine",{
"margin-top" : (window.innerHeight - this.options.height)/2 +"px",
"margin-left" : (window.innerWidth - this.options.width)/2 +"px"
});
settingStyle += getStyle(".container",{
"height" : this.options.height+"px",
"width" : this.options.width - this.options.handleWidth +"px",
"border-width" : this.options.machineBorder + "px",
"border-color" : this.options.machineColor + " " + getLighter(this.options.machineColor)
});
var winnerSize = 1.2*Math.max(this.options.height,this.options.width);
settingStyle += getStyle(".winner:before,.winner:after",{
"height" : winnerSize+"px",
"width" : winnerSize+"px",
"top" : (this.options.height-winnerSize)/2 - 20 + "px",
"left" : (this.options.width-winnerSize)/2 - this.options.handleWidth + "px"
});
settingStyle += getStyle(".handle",{
"margin-top" : this.options.height/2-this.options.handleHeight+"px"
});
document.querySelector("#setting").innerHTML = settingStyle;
//remove old cols
if (this.colArr && this.colArr.length > 0)
for (var i=0;i<this.colArr.length;i++){
container.removeChild(this.colArr[i].getDOM());
}
this.colArr = [];
// add new cols
for(var i=0;i<this.options.colNum;i++){
var col = new SlotColumn();
col.init(this.options.names.slice(0,this.options.rowNum),isShuffle);
this.colArr.push(col);
document.querySelector(".container").appendChild(col.getDOM());
}
machine.style.opacity = "1";
}
SlotMachine.prototype.addListener = function(){
var BannerFlow=arguments[0],timer,
that = this ,
container = document.querySelector(".container");
if (typeof BannerFlow!= 'undefined') {
// BannerFlow event
BannerFlow.addEventListener(BannerFlow.RESIZE, function() {
//clearTimeout(timer);
//timer = setTimeout(function(){that.init(BannerFlow);that.beforeRun()},500);
});
BannerFlow.addEventListener(BannerFlow.CLICK, function() {
that.beforeRun();
});
} else {
// Window event
window.addEventListener('resize', function(){
//clearTimeout(timer);
//timer = setTimeout(function(){that.init(BannerFlow);that.beforeRun()},500)
});
if (supportTouch) {
window.addEventListener("touchstart",function(){
that.beforeRun();
});
} else {
window.addEventListener("click",function(){
that.beforeRun();
});
}
}
var slotTrigger = document.querySelector("#slot-trigger");
if (slotTrigger) {
slotTrigger.addEventListener("click",function(e){
this.addClass('slot-triggerDown');
})
}
}
window[NAME]= SlotMachine;
})();
/*--------------=== Slot Column definition ===--------------*/
(function(){
var NAME = "SlotColumn";
SlotColumn = function(){
this.col = document.createElement("div");
this.col.className = "col";
this.init = this.init.bind(this);
this.run = this.run.bind(this);
this.beforeRun = this.beforeRun.bind(this);
this.getResult = this.getResult.bind(this);
this.getDOM = this.getDOM.bind(this);
this.arr = [];
this.colHeight=this.rowHeight=0;
this.loop = 2;
}
SlotColumn.prototype.init = function(){
this.col.empty();
this.arr=arguments[0];
var isShuffle=arguments[1];
if(isShuffle) shuffle(this.arr);
for(var i=0; i<this.arr.length*this.loop;i++){
var row = document.createElement("div");
row.className = "row "+this.arr[i%this.arr.length];
this.col.appendChild(row);
}
this.top = 0;
}
SlotColumn.prototype.beforeRun = function(){
this.halfHeight = this.col.offsetHeight/this.loop;
this.colHeight = this.col.scrollHeight/2;
this.rowHeight = this.colHeight/this.arr.length;
this.nextResult = arguments[0];
var next = this.arr.indexOf(this.nextResult);
if (next==-1) next=random(0,this.arr.length-1)|0;
var s = this.top + (random(2,10)|0)*this.colHeight + ((next+0.5)*this.rowHeight|0) - this.halfHeight;
var n = (random(2,6)|0) * fps;
this.speed = 2*s/(n+1);
this.acceleration = this.speed/n;
}
SlotColumn.prototype.getResult = function(){
var result = Math.ceil(((this.halfHeight-this.top)%this.colHeight)/this.rowHeight)-1;
//console.log(this.top,result,this.arr[result],this.halfHeight,this.colHeight,this.rowHeight);
return this.arr[result];
}
SlotColumn.prototype.run = function(){
if(this.speed <= 0) return true;//completed
this.top = (this.top - this.speed) % this.colHeight;
this.speed -= this.acceleration;
this.top %= this.colHeight;
this.col.style.transform = "translateY("+this.top+"px)";
return false;//not completed
}
SlotColumn.prototype.getDOM = function(){
return this.col;
}
window[NAME] = SlotColumn;
}());
/*--------------=== Utils definition ===--------------*/
//random in range
var random = function(){
var isNumeric = function(n){return !isNaN(parseFloat(n)) && isFinite(n)},
val = Math.random(),
arg = arguments;
return isNumeric(arg[0]) ? isNumeric(arg[1]) ? arg[0] + val*(arg[1] - arg[0]) : val*arg[0] : val;
};
//shuffle an array
var shuffle = function(arr){
var j,tmp;
for(var i=0;i<arr.length;i++){
j = random(arr.length)|0;
tmp = arr[i];arr[i]=arr[j];arr[j]=tmp;
}
}
//get CSS3 style
var setStyleCss3 = function (object, key, value) {
object.style['-webkit-'+ key] = value;
object.style['-moz-'+key] = value;
object.style['-ms-'+key] = value;
object.style[key] = value;
}
//get name from url
var getNameFromUrl = function(url){
if (url) {
var s=url.lastIndexOf("/")+1,e =url.lastIndexOf(".");
return s<e ? url.substring(s,e) : "";
}
return "";
}
//get style from object style
var getStyle = function(selector,styleObj){
var isAttribute = false;
var newStyle = selector+"{";
for(var attr in styleObj) {
if (styleObj[attr]) {
isAttribute = true;
newStyle += attr+" : "+styleObj[attr]+";";
}
}
newStyle+="}";
return isAttribute ? newStyle : "";
}
// get lighter color from rgba colors
var getLighter = function(rgba){
var o = /[^,]+(?=\))/g.exec(rgba)[0]*0.75;
return rgba.replace(/[^,]+(?=\))/g,o);
}
//remove html from text
if (!String.prototype.strip) {
String.prototype.strip = function() {
return this.replace(/(<[^>]+>)/ig," ").trim();
}
}
//remove all child node
if (!Node.prototype.empty) {
Node.prototype.empty = function(){
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
}
if (!HTMLElement.prototype.hasClass) {
Element.prototype.hasClass = function(c) {
return (" "+this.className+" ").replace(/[\n\t]/g, " ").indexOf(" "+c+" ") > -1;
}
}
if (!HTMLElement.prototype.addClass) {
HTMLElement.prototype.addClass = function(c) {
if (!this.hasClass(c)) this.className += (" " +c);
return this;
}
}
if (!HTMLElement.prototype.removeClass) {
HTMLElement.prototype.removeClass = function(c) {
if (this.hasClass(c)) this.className = (" "+this.className+" ").replace(" "+c+" "," ").trim();
return this;
}
}
/*--------------=== Main function ===--------------*/
var timer,widget = null;
if (typeof BannerFlow != 'undefined') {
BannerFlow.addEventListener(BannerFlow.SETTINGS_CHANGED, function() {
clearTimeout(timer);
timer = setTimeout(function(){
if (widget==null) {
widget = new SlotMachine();
widget.addListener(BannerFlow);
}
widget.init(BannerFlow);
widget.beforeRun();
},500);
});
}else {
window.addEventListener("load",function(e){
if (widget==null) {
widget = new SlotMachine();
widget.addListener();
}
widget.init();
widget.beforeRun();
})
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.