0

In this project of "whack-a-mole game", I have to create a visual effect of when a popped up mole is "whacked". I've decided that when I click on the mole, I want it to create a radiating circle animation effect. I have tried to accomplish the task with only CSS although some JS starter code was given.

I posted a snippet of the code and I have to post all of it in order for the game to work. As you can see, whenever I click on a "mole head", it does create the circle but it surrounds the mole-head div only and then disappears really quickly. It does not seem to create the intended animated effect I am looking for which is when you click on the head or in the area, it will create an effect like the picture shown below:

enter image description here

If I have too much code or have not formatted anything right I apologize ahead of time. Jake has provided a solution and has kindly given me a solution with just the circles but I have provided my problem.

let score = 0;
let molesLeft = 30;
let popupLength = 3000;
let hideTimeout;
let clickable = false;

function popUpRandomMole() {
  if (molesLeft <= 0) {
    document
      .querySelector(".sb__game-over")
      .classList.remove("sb__game-over--hidden");
    return;
  }

  const moleHeads = document.querySelectorAll(".wgs__mole-head");

  if (moleHeads.length === 0) {
    return;
  }
  const moleIndex = Math.floor(Math.random() * moleHeads.length);
  const moleHead = moleHeads[moleIndex];

  clickable = true;

  // UNCOMMENT THIS LINE OF CODE WHEN DIRECTED
  moleHead.classList.remove(
    "wgs__mole-head--hidden",
    "wgs__mole-head--whacked"
  );

  molesLeft -= 1;
  document.querySelector(".sb__moles").innerHTML = molesLeft;

  hideTimeout = setTimeout(() => hideMole(moleHead), popupLength);
}

function hideMole(mole) {
  clickable = false;
  mole.classList.add("wgs__mole-head--hidden");

  setTimeout(popUpRandomMole, 500);
}

window.addEventListener("DOMContentLoaded", () => {
  setTimeout(popUpRandomMole, 0);

  const moleHeads = document.querySelectorAll(".wgs__mole-head");
  for (let moleHead of moleHeads) {
    moleHead.addEventListener("click", (event) => {
      if (!clickable) return;
      score += 1;
      document.querySelector(".sb__score").innerHTML = score;
      popupLength -= popupLength / 10;

      clearTimeout(hideTimeout);
      hideMole(event.target);

      // UNCOMMENT THIS LINE OF CODE WHEN DIRECTED
      event.target.classList.add("wgs__mole--hidden");

      // UNCOMMENT THIS LINE OF CODE WHEN DIRECTED FOR THE BONUS
      event.target.classList.add("wgs__mole-head--whacked");
    });
  }
});
/* Your code here */
.wgs {
  height: 241px;
  position: relative;
  width: 320px;
  display: inline-block;
  overflow: hidden;
}

.wgs__mole-head {
  position: absolute;
  height: 178px;
  width: 188px;
  left: 55px;
  transition: margin-top 0.25s;
}

.wgs__dirt-pile {
  position: absolute;
  height: 110px;
  width: 320px;
  top: 130px;
}

.wgs__mole-head--hidden {
  margin-top: 482px;
}

.pf {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 1fr 1fr;
}

/* UNCOMMENT THE CODE BELOW WHEN DIRECTED */
.sb {
  background-color: cornflowerblue;
  border-bottom: 1px solid #645ded;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
  color: white;
  display: flex;
  font-size: 30px;
  margin-bottom: 50px;
  padding: 10px 20px;
}

.wgs__mole-head--whacked {
  border-radius: 50%;
  border: 5px solid blue;
  position: absolute;
  opacity: 0;
  animation: circle 1s ease-out;
  width: 20px;
  box-sizing: border-box;
  pointer-events: none;
  aspect-ratio: 1/1;
  transform: translateX(-50%) translateY(-50%);
}

@keyframes circle {
  0% {
    width: 20px;
    opacity: 1;
  }

  100% {
    width: 100px;
    opacity: 0.2;
  }
}

*/ .sb__mole-counter {
  flex: 1 0 0;
  text-align: right;
}

.sb__score-holder {
  flex: 1 0 0;
}

.sb__game-over--hidden {
  display: none;
}
<link href="https://github.com/RandyGoldsmith/practice-for-prepwork-css-whack-a-mole/blob/main/mole.css" rel="stylesheet"/>
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="mole.css" />
    <script type="text/javascript" src="mole.js"></script>
  </head>
  <body>
    <div class="pf">
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked"
        >
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile" >
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs wgs__mole--whacked">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hidden wgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
      <div class="wgs">
        <img
          src="https://png.pngtree.com/png-clipart/20210425/original/pngtree-mole-head-vector-png-image_6256794.png"
          class="wgs__mole-head wgs__mole-head--hiddenwgs__mole-head--whacked">
        <img src="https://static.wikia.nocookie.net/scribblenauts/images/a/a8/Mole_Hill.png/revision/latest?cb=20140412011314" class="wgs__dirt-pile">
      </div>
    </div>

    <div class="sb">
      <div class="sb__score-holder">Score <span class="sb__score">0</span></div>
      <div class="sb__game-over sb__game-over--hidden">Game Over</div>
      <div class="sb__mole-counter">
        Moles <span class="sb__moles">30</span>
      </div>
    </div>
  </body>
</html>
Randy Goldsmith
  • 327
  • 3
  • 17
  • Not a fix but note that the [](https://html.spec.whatwg.org/dev/embedded-content.html#the-img-element) tag does not use and does not need a closing slash and never has in any HTML specification. – Rob Mar 09 '23 at 10:18
  • Reading this : https://stackoverflow.com/questions/14860492/how-to-close-img-tag-properly, there is a lot of back and forth and technicalities for which from what I read, the ending slash doesn't hurt. My coding editor automatically puts it in at the end. But for arguments sake, I have seen both everywhere. Thank you – Randy Goldsmith Mar 13 '23 at 17:29
  • Your link is to SO users. My link is to the HTML specification written by the browser vendors themselves. And they don't say anything about using it except (elsewhere) you can put the slash there but 1) it does nothing 2) it has no meaning and 3) Browsers are instructed to ignore it. In addition, the W3C HTML Validator flags it and gives a message saying essentially the same thing. iow, [it's pointless](https://github.com/validator/validator/wiki/Markup-%C2%BB-Void-elements#trailing-slashes-in-void-element-start-tags-do-not-mark-the-start-tags-as-self-closing) and makes no sense to use it. – Rob Mar 13 '23 at 19:57

1 Answers1

0

It's hard to say what exactly all the problems are - things like "keyframes aren't working" are not very descriptive (especially since you said the animation is going too fast, which makes it seem like the keyframes ARE working). I'm guessing that this is at least partially because you are scaling your circle from 300*.5 = 150px wide, all the way up to 300*2.5=850px in just 2 seconds. That is going to look pretty fast.

The source code you've provided is a good start, but it has some issues and doesn't do a good job illustrating your overall problem. I tried to put it into a Fiddle just to play around with it, but right away the HTML is not legally formatted, and you haven't included the definition for popUpRandomMole, so the JS doesn't run either.

So instead I made a barebones implementation of how I would do JUST the expanding circle effect on a click event:

var container = document.getElementById("container");
var moles = document.getElementsByClassName("molehead");

for (let mole of moles)
{
    mole.addEventListener("click", onClick);
}


function onClick(event){
    var radiatingCircleEl = document.createElement("div");
  radiatingCircleEl.classList.add("radiating");
  
  radiatingCircleEl.style.top = event.offsetY + event.currentTarget.offsetTop + "px";
  radiatingCircleEl.style.left = event.offsetX + event.currentTarget.offsetLeft + "px";
  
  container.appendChild(radiatingCircleEl);
  setTimeout(() => radiatingCircleEl.remove(), 900);  // delete the circle after 900ms, so we dont fill up our DOM
  
  event.stopPropagation();
}
.molehead{
  width: 100px;
  height: 100px;
  margin: 20px;
  background-color: brown;
}

#container{
  display: flex;
  position: relative;
  border: 1px solid lightgrey;
}

.radiating{
  border-radius: 50%;
  border: 5px solid blue;
  position: absolute;
  animation: radiate 1s ease-out;
  aspect-ratio: 1/1;
  width: 20px;
  box-sizing: border-box;
  transform: translateX(-50%) translateY(-50%);  /* center the circle */
  pointer-events: none;
}

@keyframes radiate{
  0%{
    opacity: 1;
    width: 20px;
  }
  100%{
    opacity: .2;
    width: 100px;
  }
}
<div id="container">
  <div class="molehead">
    This is a mole
  </div>
  <div class="molehead">
    This is a mole
  </div>

</div>

Hopefully this gives you some ideas on how to move forwards. If not, please take another pass at your code, try to make it into a working, minimal reproducible example, preferably as a Stack Overflow snippet (such as the one I have provided above), and I will be happy to take a closer look and help you debug it.

Jake
  • 862
  • 6
  • 10
  • I have created a working snippet and hope it's not to much code and can also help you see what I am seeing. – Randy Goldsmith Mar 10 '23 at 00:00
  • Well in this example, you are applying your blue border class `wgs__mole-head--whacked` directly into the mole's `` tag. This is applying all the styles in your `wgs__mole-head--whacked` directly to the image of the mole head, such as giving the image a blue border, making it round (border-radius: 50%) and translating it up and to the left. Simultaneously, you are calling `hideMole`, which is applying `wgs__mole-head--hidden ` after a 500ms delay, which shifts your mole downwards by 482px. – Jake Mar 10 '23 at 01:07
  • As a side note, I do want to point out that you are applying this class `wgs__mole--hidden` as well whenever you click a mole image, but this class isn't actually defined in your CSS and so is doing nothing. Not sure if this is intentional or not – Jake Mar 10 '23 at 01:08
  • I don't know if this helps you with your question or not. Broadly, I would look at merging my solution into yours - the most important difference is that onclick, you will need to create and attach a new element to the DOM to represent your expanding circle. Applying the styles for the expanding circle directly onto the mole `` tag isn't going to work out – Jake Mar 10 '23 at 01:10