'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 |