# Coin Flip Web App Made using JavaScript, HTML and CSS animations

During one of our class discussions, we talked about the functionality that would be involved in a program that simulates the flipping of a coin. Under the original circumstances, we needed a button that once clicked our program runs through an array of turns and produces a random outcome (either one and two) for each iteration. When you finish iterating over the array of turns, you will have an array full of ones and twos. If there were more ones, then the JavaScript would print out that ‘Heads’ was the winner. If there were more twos in the array, then ‘Tails’ would be the winner. I found this to be a riveting discussion topic. SO interesting in fact, that I have spent over a week building out my very own coin flipping web app. Is your mind blown yet?

OK, Sophia. Maybe you don’t find the initial concept interesting, but I don’t find you interesting! You are the least interesting of all the Golden Girls. All you do is nag and bring down the other more entertaining Golden Girls who are just trying to live their lives. Betty White for life!

Where was I? Oh, yes, the exciting world of coin flipping.

I can’t say I blame Sophia for not finding the original design interesting. Here were a few problems I had with it:

1. There was no active record of wins
2. The program ran through all the turns at once
3. Very little interaction, aside from clicking a button and seeing a message
4. Minimal celebration of victory

It’s true. In the original design, you clicked a button (yay?) and then boom ‘x’ number of turns are finished instantaneously and there’s a winner. It worked…but that was it? So after figuring out the initial functionality, I thought I’d keep going and make it so the users could go one turn at a time. I was able to achieve this by separating the the flipping functionality and the turn iteration into two separate methods:

`function coinFlip() {  function flip(){      return Math.floor((Math.random() * 2) + 1)  }  var result = flip();  if (result === 1){     document.getElementById("coin").src="images/heads.png";     winner = `HEADS`;     head_win = heads_wins.push(result);     document.getElementById("head_win").innerText = head_win;   } else if (result === 2) {     document.getElementById("coin").src="images/tails.png";     winner = `TAILS`;     tail_win = `\${tails_wins.push(result)}`;     document.getElementById("tail_win").innerText = tail_win;   }   document.getElementById("winner").innerText = winner;}`

The `coinFlip()` method handles the actual flipping of the coin, as well as printing out which side of the coin prevailed. The user clicks an image of a quarter, and the `onclick` event handler makes the image spin. `flip()` controls the random numerical outcome. If the result of `flip()` is 1, `coinFlip()` prints `HEADS` and displays the heads side of a quarter. If it’s 2, `coinFlip()` prints `TAILS` and displays the tails side of the coin. The outcomes are stored in two arrays: `heads_wins` stores all the 1 outcomes and `tails_wins` stores all the 2 outcomes. `coinFlip()` also prints the current length of each array after the coin is flipped. These values can be seen in the score box which updates after every turn. Then we have a method that keeps score:

`function score(){  if (heads_wins.length + tails_wins.length === 9){    if (heads_wins.length > tails_wins.length){      document.getElementById("coin").src="images/heads.png";      final_winner = `The winner is HEADS with \${heads_wins.length} wins!`;      print_winner();    } else if (tails_wins.length > heads_wins.length) {      document.getElementById("coin").src="images/tails.png";      final_winner = `The winner is TAILS with \${tails_wins.length} wins!`;      print_winner();    }  }}`

This stops the game after an odd number of turns (9) to ensure there is no tie. if the `heads_wins.length` is longer than `tails_wins.length`, `score()` evaluates `HEADS` as the winner. And if `tails_wins.length` is larger, then `TAILS` is the winner. Then there is another method that prints the winner, aptly named `print_winner()`.

`function print_winner(){  winner = ''  document.getElementById("final_winner").innerHTML = final_winner;  fallingCoins()}`

I guess I could have stopped there. You have a winner, a message flashes, it’s all fine and dandy. But Sophia is still not pleased. What else is new…

Wow. Harsh. What does Betty White have to say about all this?

There we go. Much better. Betty the babe is always a beacon of light and positivity. So I guess she’s OK with me stopping here. But then I thought, this is JavaScript. Let’s have some fun with it! Why not add a more profound finale to this rousing game of coin flipping. Come on. WE’RE FLIPPING A FRICKEN’ COIN!!!

So I thought, what would Betty do? Well, Betty, being the superstar she is, would make it rain. But my funds have been running a little low lately.

So we’ll make it rain quarters! How do we do that? Allow me to introduce fallingCoins():

`function fallingCoins(){  var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  if (heads_wins.length > tails_wins.length){    document.getElementById("damn").innerHTML += "<div id='coin_fall'><img id='falling_coin' src='images/heads.png'/></div>"  } else {    document.getElementById("damn").innerHTML += "<div id='coin_fall'><img id='falling_coin' src='images/tails.png'/></div>"  }  // true means clone all childNodes and all event handlers  for (var i = 0; i < arr.length; i++) {    var rand = Math.floor(Math.random() * 3) + 2;    setTimeout(addCoin, (i * rand) * 300);  }}`

I made an array (1–10) which represents the number of coins I want to generate.If the winner is heads, it will rain heads coins. If tails wins, then it will rain tails (I would like to get it so that it could rotate and show the front and back of the quarter simultaneously but that’s an undertaking for later on). Once the winner is determined, I added a `coin_fall` div, which has the child image, `failling_coin`. It is injected in the `damn` div. (I was frustrated when I wrote that). Originally I had those lines in the original html. But then I would have a random quarter just falling over and over again at the left of the screen. I only wanted to add it when someone wins. While iterating through the array, `setTimeout` is used to call a function at random times (but the range isn’t too crazy, that way we’re not waiting 5 minutes for coins). The function, `addCoin()` is where the magic happens.

`function addCoin() {  var coin_div = document.getElementById('coin_fall')  var rand = Math.floor(Math.random() * 1000) + 1  coin_div.style.position = "fixed";  coin_div.style.top = '-120px';  coin_div.style.left = rand +'px';  var clone = coin_div.cloneNode(true);  document.body.appendChild(clone);}@keyframes coin_fall {  0% {    transform: translate(0px, -20%);  } 100% {    transform: translate(0px, 1000%);  }}@keyframes infinite-spinning {  from {    transform: rotateX(0deg);  } to {    transform: rotateX(720deg);  }}`

I originally added `coin_fall` in this function, but I didn’t need to add this line AND create a new coin every time we iterate through the 10 elements of the previous array. So I just wrote that line once in `fallingCoins()`. But we grab the newly added elements here in `addCoin()`, and store that value as `coin_div`. Once the elements are added, we generate another random number. This random number will be used to determine a random point from the left of the screen (approximately between 0px and 1000px).

Now add styling to the `coin_div`, which includes a top parameter(starting point). A fixed position of `-120px` is good because `coin_div` will start the fall from the top of the page and out of view. Then the left positioning is a random number between 0 and 1000 so it can appear anywhere on the screen. After the styling is added, `coin_div` is cloned with am `true` value. That way the original element as well as any children and event listeners/animations (the child in this case being `falling_coin`) are cloned.

Since you can’t apply two animations to one element, I had to apply one animation to the `img` and the other to the `coin_fall` div. See below.

`@keyframes coin_fall {  0% {    transform: translate(0px, -20%);  } 100% {    transform: translate(0px, 1000%);  }}@keyframes infinite-spinning {  from {    transform: rotateX(0deg);  } to {    transform: rotateX(720deg);  }}`

Translate is a css transformation that changes the position of the element in the window. RotateX is used to rotate the element in place on its X access (up and down). A full rotation is 720 degrees. And for styling the `div` and `img`, I set the animation to occur over the 4 seconds, that way it moves slowly enough for you to actually see and enjoy the animation.

`#coin_fall{  animation: coin_fall 4s infinite;  position: fixed;}#falling_coin {  width: 100px;  animation: infinite-spinning 4s infinite;  margin: 0;}`

One roadblock I encountered was when I was trying to get the coin to flip when the user presses it. The problem: css doesn’t recognize `onclick` as a selector like it would `hover`. Instead, I utilized `active` which executes the animation so long as the user is holding down the click.

`input:active{  transform: rotateX(1800deg) scale(4);}`

But we can’t expect the user to hold down their click on the image, wait for the animation to finish and then release in order to see the outcome. To get around this, I made the rotation a high number (but made sure to keep it a multiple of 360 so it would complete on a full spin), and set the transition to half a second. This way, you accomplish more of the full animation in a fraction of the time it takes to click.

`input {  margin-left: 42.5%;  margin-right: 42.5%;  width: 15%;  transition: all .5s linear;}`

Thus simulating a flipping animation that occurs `onclick`.

So here it is, Heads or Tails. The moment Betty White has been waiting for and Sophia has been loathing.

Viola! We have ourselves a pretty neat coin flipping web app. You may have noticed however, that some of the falling coins are glitchy. Sometimes they disappear before they reach the bottom of the page. Other times they continue heading down the page but randomly change course and jump to another part of the screen. Sometimes it looks like the coins are generated not `-120px` off screen, but in the middle of the page. I have a hypothesis:

When I look at the execution in console, you can clearly see there are a few different places where `coin_div` is added to the html:

So it looks like the creation and positioning is working fine, the top is constant and then the left pixel value is a random number between 0 and 1000. But you see, there is that one value that gets added under `damn` and the rest are prepended to the body of the webpage, above the damn div. I’ve tried doing one or the other but it only either produces one new element or produces a bunch but they produce rapid fire and is doesn’t look like seamless generation.

I am also curious if it has something to do with the css styling. Maybe the divs or the images are impinging on space and ultimately push each other to the side. Or maybe the margins are overwhelmed, resulting in mismatched starting/ending points. I have been able to overcome almost every bug that I have ran into. And I will figure this one out too. But for now, I just can’t look at it anymore. This…this code…has become the bane of my programming existence. The Mozart to my Salieri. But it wasn’t the code that was mocking me. It was God!

If you enjoyed the post or need clarification on anything mentioned, let me know in the comments. Feel free to share and leave claps!

# References

Code 📲💻 Wellness 🧘🏻‍♂️😌

## More from Matthew Croak

Code 📲💻 Wellness 🧘🏻‍♂️😌

## Get Out of Tutorial Hell

Get the Medium app