Slot machine animation with vanilla js

by Lucas Almeida

HTML

<div class="slot-machine">
  <div class="slot-machine__slots">
    <div class="slot slot-machine__slot"></div>
    <div class="slot slot-machine__slot"></div>
    <div class="slot slot-machine__slot"></div>
  </div>
  <button type="button" id="start" class="slot-machine__button">Roll</button>
  <div id="log"></div>
</div>

SCSS

$dark: #16213E;
$overlay: rgba(0,0,0,.2);
$midtone: #0F3460;
$highlight: #5C2E7E;
$radius: 5px;

body {
  background-color: $dark;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.slot-machine {
  padding: 20px;
  background-color: $midtone;
  border-radius: $radius;
  
  &__slots {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-gap: 20px;
    padding: 20px;
    background-color: $overlay;
    border-radius: $radius;
    margin-bottom: 10px;
  }
  
  &__slot {
    width: 100px;
    height: 100px;
    overflow: hidden;
    
    img {
      display: block;
    }
  }
  
  &__button {
    display: block;
    width: 100%;
    height: 40px;
    background: $highlight;
    border: 0;
    text-transform: uppercase;
    color: white;
    padding: 0 20px;
    font-size: 20px;
    border-radius: $radius;
    cursor: pointer;
    
    &:hover {
      opacity: 0.7;
    }
  }
}

#log {
  max-width: 380px;
  font: normal 14px sans-serif;
  color: white;
  word-wrap: break-word;
}

JavaScript

function shuffle(array) {
  let currentIndex = array.length,  randomIndex;

  while (currentIndex != 0) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;

    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]];
  }

  return array;
}

const getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const removeAllChildNodes = (parent) => {
    while (parent.firstChild) {
        parent.removeChild(parent.firstChild);
    }
}

// List of prizes
const prizes = [
	'https://assets.gamersclub.com.br/marketplace/double-rating-points-20-matches-sub',
  'https://assets.gamersclub.com.br/marketplace/dot-say-desenrola-bate-morre-de-ladinho',
  'https://assets.gamersclub.com.br/marketplace/medal-trevo-dourado-loja',
  'https://assets.gamersclub.com.br/marketplace/gold_bulk.png',
  'https://assets.gamersclub.com.br/marketplace/medal-slot-flash',
]

const slots = document.getElementsByClassName('slot');
const defaultSize = 100;
const totalDuplicates = 7;

// Clear slots and recreate random list of images
const buildItemLists = (playerWon, winningItem, randomDifference) => {  
  // Iterate through the slot html elements
  Array.prototype.forEach.call(slots, (slot, s) => {
    let prizeBlocks = document.createElement('div');
    prizeBlocks.classList.add('slot-machine__prizes');
    
    // Generate prize log
    const log = document.getElementById("log");
	  log.innerHTML= `Ganhou: ${playerWon ? "Sim" : "Não"}<br> ${playerWon ? `Item sorteado: ${winningItem}` : ""}`;

		// Multiply and shuffle prize images for visual purposes
    randomPrizes = shuffle(prizes.flatMap(i => Array(totalDuplicates).fill(i)));
    randomPrizes.forEach((prize) => {
      let prizeElement = document.createElement('img');
      prizeElement.setAttribute('src', prize);
      prizeElement.setAttribute('width', defaultSize);
     ...