<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();
  })
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.