I'm creating a random image generator that displays images when a button is clicked. I'm trying to prevent the same image being displayed twice in a row by having the random number connected to each image increase by 1 if duplicated (in other words the next image will be shown rather than the same image twice). I'm trying to use if statements to achieve this but there seems to be a glitch in my code as the same image is still being displayed more than once. Not sure where the problem is. Any solutions out there ?
Thanks
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
var pic1 = href="http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg";
var pic2 = href="http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg";
var pic3 = href="http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg";
var num = Math.floor(Math.random() * (3 - 1 +1)) + 1;
if(num !== 2 && num !== 3) {
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
} else if (num !== 1 && num !== 3) {
if(ranImgDis.src !== pic2) {
ranImgDis.src = pic2;
} ranImgDis.src = pic3;
} else if (num !== 1 && num !== 2) {
if(ranImgDis.src !== pic3) {
ranImgDis.src = pic3;
} ranImgDis.src = pic1;
}
}
You are missing an else in all your inner if statements. The result is that even if the code in the if statement is executed, the code after it is always executed and replaces what the code inside the if statement did.
You code like this:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
should be:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} else {
ranImgDis.src = pic2;
}
You can make the code simpler and more flexible by putting the images in an array, and keep the index of the current image rather than checking the source of the image. You can use the length of the array when you create the random number, then you can just add more images to the array without changing anything else in the code.
var pics = [
"http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg".
"http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg",
"http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg"
];
var current = 0;
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
// get a random number within a range one less than the number of images
var num = Math.floor(Math.random() * (pics.length - 1)) + 1;
// use the random number to pick a different image from the current one
current = (current + num) % pics.length;
ranImgDis.src = pics[current];
}
This'll work, and let you expand the number of images beyond three.
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
var pics = [
"http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg",
"http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg",
"http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg"
]
var currentSrc = document.getElementById('ranImgDis').src
var newSrc = currentSrc
while (newSrc == currentSrc) {
newSrc = pics[Math.floor( Math.random() * pics.length )]
}
ranImgDis.src = newSrc
}
JSFiddle of it at http://jsfiddle.net/X7HM2/
Why dont you change the logic abit.
Rename the images to numbers from 1 to 3 .
Than generate the random number between 1 to 3 and if that random number is same as currently loaded image regenerate the number , this logic will help you even when you will add images from 3 to finite limit.
Your logic is a bit messy, and also there are some obvious problems like:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
This will unconditionally set ranImgDis.src to pic2 at the end of the day. So maybe you should think this over. I suggest you to maintain an array instead to avoid dupes.
Related
I have a random number generator that gives me a value between 1 and 6 (N).
I want to change the image SRC based on what number I get.
for instance, I have 6 images named [image1, image2, image3, image4, image5, image6].
let N = Math.random() * 6;
N = Math.floor(N);
document.querySelector(".img").src = `images/image${N}.png `;
I think the problem is caused by JS parsing images/img${N}.png as a HTML code due to ${N} being JavaScript code and HTML not being able to assign a value to it.
is there another way of writing this without using if / else if for every value of N?
like so =>
let N = Math.random() * 6;
N = Math.floor(N);
if (N === 1) {
document.querySelector(".img1").src = "images/image1.png";
} else if (N === 2) {
document.querySelector(".img1").src = "images/image2.png";
} else if (N === 3) {
document.querySelector(".img1").src = "images/image3.png";
} else if (N === 4) {
document.querySelector(".img1").src = "images/image4.png";
} else if (N === 5) {
document.querySelector(".img1").src = "images/image5.png";
} else {
document.querySelector(".img1").src = "images/image6.png";
}
Your problem is a superfluous space at the end of the template/string
document.querySelector(".img").src = `images/image${N}.png `;
// ^
and missing one for one based counting.
Your actual random values are 0 ... 5, but you need 1 ... 6.
You could take a shorter approach by moving the random/flooring part into the expression.
document.querySelector(".img").src = `images/image${Math.floor(Math.random() * 6) + 1}.png`;
const n = Math.floor(Math.random() * 6) + 1;
console.log(`images/image${n}.png`);
You can use array index like this:
let N = Math.random() * 6;
N = Math.floor(N);
const imgs = [image1, image2, image3, image4, image5, image6]
document.querySelector(".img1").src = imgs[N];
You can use something like this :
let N = 6 // no of images
const imageBase='images/image';// relative or absolute url
document.querySelector(".img").src = `${imageBase}${Math.floor(Math.random() * N)}.png`;
I can't seem to find any solutions.
I want to create a form that collects 4 nicknames after submit a form and then displays them all randomly in html code using javascript
My 4 input values are now in an array.
I have to display them randomly in two different teams.
I'm trying to get a random index, and as long as it's different from the ones already assigned to avoid one person being on both teams.
This code works, but sometimes, one player is assigned to 2 teams. Then, the randomizer doesn't work... Do you have an idea ?
function getRandomNumber(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getData() {
let joueur1 = document.querySelector("#player1").value;
let joueur2 = document.querySelector("#player2").value;
let joueur3 = document.querySelector("#player3").value;
let joueur4 = document.querySelector("#player4").value;
playerList.push(player1.value);
playerList.push(player2.value);
playerList.push(player3.value);
playerList.push(player4.value);
randomNumber1 = getRandomNumber(playerList.length);
last1 += randomNumber1;
random1.textContent = playerList[randomNumber1];
do {
randomNumber2 = getRandomNumber(playerList.length);
} while (randomNumber2 == last1 && last4 && last3);
last2 += randomNumber2
random2.textContent = playerList[randomNumber2];
do {
randomNumber3 = getRandomNumber(playerList.length);
} while (randomNumber3 == last1 && last2 && last4);
last3 += randomNumber3
random3.textContent = playerList[randomNumber3];
do {
randomNumber4 = getRandomNumber(playerList.length);
}while (randomNumber4 == last1 && last2 && last3)
random4.textContent = playerList[randomNumber4];
last4 += randomNumber4
}
Thanks for your help !
Here is a simple way of getting a random item from your array
Here you add your items into array
let joueur1 = document.querySelector("#player1").value;
let joueur2 = document.querySelector("#player2").value;
let joueur3 = document.querySelector("#player3").value;
let joueur4 = document.querySelector("#player4").value;
let playerList=[];
playerList.push(joueur1);
playerList.push(joueur2);
playerList.push(joueur3);
playerList.push(joueur4);
Then, Here is how you can get randomized content
let randomPlayer = playerList[Math.floor(Math.random() * playerList.length)];
Math.random() will never be 1. The largest index is always one less than the length of the array
I have to change background image in method. Background images are coming from this.items service but when method runs new background image shouldn't be same with previous one.
When I run this method it changes images but new image can be same with previous one. How can I do?
export class GridManager {
changeBackground() {
var x = Math.floor(Math.random() * document.querySelectorAll(".grid-item").length);
if (this.items[x].backgroundImage != "" && this.items[x].backgroundImage != null) {
document.querySelector(".container").style.backgroundImage = `url('${this.items[x].backgroundImage}')`;
}
}
}
You need to check if the value is in the array, if exist remove it or do whatever you need to do
function checkItem(array,checkItem){
for( var i=0;i<array.length;i++){
if(array[i] == checkItem){
var removedItem= array.splice(checkItem,1); // your can remove it
/*or simply do your code here */
}
}
}
There's a lot of solutions, to give you another one not mentioned here, you can do a custom generate random number that excludes the previous index that you got.
something like:
class GridManager {
prevIndex = null;
generateRandom(min, max, excludedIndex) {
var num = Math.floor(Math.random() * (max - min + 1)) + min;
return (num === excludedIndex) ? this.generateRandom(min, max, excludedIndex) : num;
}
changeBackground() {
var x = this.generateRandom(0, document.querySelectorAll(".grid-item").length - 1, this.prevIndex);
this.prevIndex = x;
if (this.items[x].backgroundImage != "" && this.items[x].backgroundImage != null) {
document.querySelector(".container").style.backgroundImage = `url('${this.items[x].backgroundImage}')`;
}
}
}
As of now, my code successfully goes from one image to another upon clicking on it.
However, the issue I'm facing is that once you get to the last image and click (to redirect user to indexTwo.html), it takes the user back to the first image for like 2 seconds and then it redirects to indexTwo.html.
My question is: How would I prevent that behavior from happening? In other words: click through all the images and once the last image's clicked, redirect user to indexTwo.html without seeing the first image at all.
Note: I know if (imageId === 0) {...} statement is the culprit but not sure how to go about fixing it.
let theImage = document.getElementById('the-image');
let index = [
"http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png",
"https://cdn.tutsplus.com/net/uploads/legacy/155_drupal/200x200.png",
"https://townandcountryremovals.com/wp-content/uploads/2013/10/firefox-logo-200x200.png"
];
let op = 1;
let imageId = 0;
let clickedImage = () => {
// start animation opacity
if(op === 1) {
let timer = setInterval(() => {
if(op <= 0.1) {
// load the next image
imageId = (1 + imageId) % index.length;
theImage.src = index[imageId];
// reset the opacity
theImage.style.opacity = op = 1;
clearInterval(timer);
if (imageId === 0) {
window.location = "indexTwo.html";
}
} else {
op -= 0.1;
theImage.style.opacity = op;
}
}, 50)
}
};
do you need to verify the datatypes match for imageId and the number 0? if not, try using == instead of ===
I am trying to finish my converter, and at one point I did have it working but now some of the code won't work. Like any conversion from LBS. I found out that unrelated parts of the code effect other parts, because I erased the essential parts of the code, and then pasted back in part by part to see where it messed up. For example when I put just the part of the code that converts LBS to other units, it works fine, as you can see in the examples below, but when I put the conversion for grams, it does not work. Why are different parts of my code effecting each other, just by being in the same click function?
var main = function() {
var bttn = $('.sbs');
bttn.click(function(){
var rslt = $('#result');
var num = $('#nmbr').val();
var inpt = $('#slct1').val();
var outpt = $('#slct2').val();
//Converstion from pounds
if(inpt == 'pounds'){
if(outpt == 'grams') {
var pGrams6 = num * 453.59;
rslt.text(pGrams6);
} if(outpt == 'kiloGrams') {
var pKilo6 = num * 2.2;
rslt.text(pKilo6);
} if(outpt == 'ounces') {
var pOunce6 = num * 16;
rslt.text(pOunce6);
} if(outpt == 'milliGrams') {
var pMilo6 = num * 453592;
rslt.text(pMilo6);
}
}
//Conversion from grams
if(inpt = 'grams') {
if(outpt == 'pounds') {
var pPound5 = num / 453.59;
rslt.text(pPound5);
} if(outpt == 'kiloGrams') {
var pKilo5 = num / 1000;
rslt.text(pKilo5);
} if(outpt == 'ounces') {
var pOunce5 = num * 28.35;
rslt.text(pOunce5);
} if(outpt == 'milliGrams') {
var pMilo5 = num * 1000;
rslt.text(pMilo5);
}
}
});
}
$(document).ready(main);
FULL CODE: https://jsfiddle.net/qete67cz/
This line is the problem:
if(inpt = 'grams') {
You want ==, not =. As it is, that if test will always be true because you're assigning a non-empty string.
In general, when you're testing something to see if its some value or some other value, you probably should use if ... else if instead of a simple sequence of if statements.