'How to Make All Images Spin at the Same Time in JavaScript?

I am creating a simple spinner game that matches 3 images from a predifned array. Now when i click on start it starts spinning the first image only and the three images stay static, when i click stop the next image starts spinning and so on.

How can i make it so that they all spin at the same time?

here is my code:

const pix = ["https://picsum.photos/id/236/100", "https://picsum.photos/id/237/100", "https://picsum.photos/id/238/100", "https://picsum.photos/id/239/100", "https://picsum.photos/id/240/100", "https://picsum.photos/id/241/100"];
    
    const currPix = [
      document.getElementById("image1"),
      document.getElementById("image2"),
      document.getElementById("image3"),
    ];
    
    // getting the difficulty buttons
    const difficultyDiv = document.querySelector(".difficulty-div");
    const difficultyButtons = document.getElementsByName("difficulty");
    let difficulty = "easy";
    for (let button of difficultyButtons) {
      button.onchange = (e) => {
        // detects change in value
        difficulty = e.target.value;
      };
    }
    
    // getting start and stop buttons
    const startGame = document.getElementById("start-button");
    const stopSpin = document.getElementById("spin-button");
    
    // stats
    let wins = 0;
    let losses = 0;
    const winNode = document.querySelector(".wins .win-count");
    const lossNode = document.querySelector(".losses .loss-count");
    
    const beginGame = (e) => {
      // function for handling game logic
    
      // some initial setup
      difficultyDiv.classList.toggle("hide");
      stopSpin.disabled = false;
      startGame.disabled = true;
    
      // start logic
      let interval;
      if (difficulty === "easy") {
        interval = 1000;
      } else if (difficulty === "medium") {
        interval = 500;
      } else {
        interval = 250;
      }
    
      for (image of currPix) {
        image.src = pix[Math.floor(Math.random() * 5)];
      }
    
      let currStop = 0;
      // set for the first image
      let intervalId = setInterval(
        () => (currPix[currStop].src = pix[Math.floor(Math.random() * 5)]),
        interval
      );
    
      stopSpin.onclick = () => {
        clearInterval(intervalId);
        currStop++;
        if (currStop == 3) {
          // remove handler
          stopSpin.onclick = () => {};
    
          // reset buttons
          stopSpin.disabled = true;
          startGame.disabled = false;
          difficultyDiv.classList.toggle("hide");
    
          // update results
          if (
            currPix[0].src === currPix[1].src &&
            currPix[1].src === currPix[2].src
          ) {
            alert("You Won!");
            wins++;
          } else {
            alert("You Lost!");
            losses++;
          }
          winNode.textContent = wins;
          lossNode.textContent = losses;
    
          for (image of currPix) {
            image.src = "initial.jpg";
          }
        } else {
          intervalId = setInterval(
            () => (currPix[currStop].src = pix[Math.floor(Math.random() * 5)]),
            interval
          );
        }
      };
    };
    stopSpin.disabled = true;
    startGame.onclick = beginGame;
        <div class="main">
          <div class="image-holder">
            <img src="https://picsum.photos/id/236/100"  id="image1" style="display: block" />
            <img src="https://picsum.photos/id/237/100"  id="image2" style="display: block" />
            <img src="https://picsum.photos/id/238/100"  id="image3" style="display: block" />
          </div>
          <div class="difficulty-div">
            Speed Level:
            <input type="radio" name="difficulty" id="easy" value="easy" checked />
            Easy
            <input type="radio" name="difficulty" id="medium" value="medium" />
            Medium
            <input type="radio" name="difficulty" id="hard" value="hard" /> Hard
          </div>
          <div class="button-group">
            <button id="start-button" type="button">Start</button>
            <button id="spin-button" type="button">Stop spinning</button>
          </div>
          <div class="stats">
            <p>
              Summary <br />
              --
            </p>
            <div class="wins">
              <h3>Wins</h3>
              <p class="win-count">0</p>
            </div>
            <div class="losses">
              <h3>Losses</h3>
              <p class="loss-count">0</p>
            </div>
          </div>
        </div>


Solution 1:[1]

You need to set the interval for all the images in one go then only you can expect them to spin together. Currently, you are doing that one by one which is the incorrect way based on your need.

Updated the code please have a look.

const pix = ["https://picsum.photos/id/236/100", "https://picsum.photos/id/237/100", "https://picsum.photos/id/238/100", "https://picsum.photos/id/239/100", "https://picsum.photos/id/240/100", "https://picsum.photos/id/241/100"];
    
    const currPix = [
      document.getElementById("image1"),
      document.getElementById("image2"),
      document.getElementById("image3"),
    ];
    
    // getting the difficulty buttons
    const difficultyDiv = document.querySelector(".difficulty-div");
    const difficultyButtons = document.getElementsByName("difficulty");
    let difficulty = "easy";
    for (let button of difficultyButtons) {
      button.onchange = (e) => {
        // detects change in value
        difficulty = e.target.value;
      };
    }
    
    // getting start and stop buttons
    const startGame = document.getElementById("start-button");
    const stopSpin = document.getElementById("spin-button");
    
    // stats
    let wins = 0;
    let losses = 0;
    const winNode = document.querySelector(".wins .win-count");
    const lossNode = document.querySelector(".losses .loss-count");
    
    const beginGame = (e) => {
      // function for handling game logic
    
      // some initial setup
      difficultyDiv.classList.toggle("hide");
      stopSpin.disabled = false;
      startGame.disabled = true;
    
      // start logic
      let interval;
      if (difficulty === "easy") {
        interval = 1000;
      } else if (difficulty === "medium") {
        interval = 500;
      } else {
        interval = 250;
      }
    
      for (image of currPix) {
        image.src = pix[Math.floor(Math.random() * 5)];
      }
    
      let currStop = 0;
      // set for the first image
      let intervalIds = currPix.map((pic)=>{return setInterval(
        () => (pic.src = pix[Math.floor(Math.random() * 5)]),
        interval)})
     
    
      stopSpin.onclick = () => {
      intervalIds.forEach((i)=>{clearInterval(i)})
        
          // remove handler
          stopSpin.onclick = () => {};
    
          // reset buttons
          stopSpin.disabled = true;
          startGame.disabled = false;
          difficultyDiv.classList.toggle("hide");
    
          // update results
          if (
            currPix[0].src === currPix[1].src &&
            currPix[1].src === currPix[2].src
          ) {
            alert("You Won!");
            wins++;
          } else {
            alert("You Lost!");
            losses++;
          }
          winNode.textContent = wins;
          lossNode.textContent = losses;
    
          for (image of currPix) {
            image.src = "initial.jpg";
          }
        
      };
    };
    stopSpin.disabled = true;
    startGame.onclick = beginGame;
<div class="main">
          <div class="image-holder">
            <img src="https://picsum.photos/id/236/100"  id="image1" style="display: block" />
            <img src="https://picsum.photos/id/237/100"  id="image2" style="display: block" />
            <img src="https://picsum.photos/id/238/100"  id="image3" style="display: block" />
          </div>
          <div class="difficulty-div">
            Speed Level:
            <input type="radio" name="difficulty" id="easy" value="easy" checked />
            Easy
            <input type="radio" name="difficulty" id="medium" value="medium" />
            Medium
            <input type="radio" name="difficulty" id="hard" value="hard" /> Hard
          </div>
          <div class="button-group">
            <button id="start-button" type="button">Start</button>
            <button id="spin-button" type="button">Stop spinning</button>
          </div>
          <div class="stats">
            <p>
              Summary <br />
              --
            </p>
            <div class="wins">
              <h3>Wins</h3>
              <p class="win-count">0</p>
            </div>
            <div class="losses">
              <h3>Losses</h3>
              <p class="loss-count">0</p>
            </div>
          </div>
        </div>

Solution 2:[2]

You could define a css class with a spinning animation:

.my-spinning-animation {
    animation: spin 1s linear;
    animation-iteration-count: infinite;
}

@keyframes spin {
    0% { transform: rotateZ(0deg) }
    100% { transform: rotateZ(360deg) }
}

Then use javascript to assign the class to each image:

for (let el of document.getElementsByTagName('img')) {
    el.classList.toggle('my-spinning-animation')
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 poo
Solution 2 chris coerdes