Simon Revill
Simon Revill

Reputation: 127

Pulling a non-repeating, random image from an array

I have searched the forum thoroughly for a solution to this with no luck. Hoping someone can help me here.

I have an empty div with no background image. When a user clicks on it, I have a function that sets the background image like this:

function myAnimation(element) {

    var images = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"];

    var random = Math.floor(Math.random() * 4);

    element.style.backgroundImage = images[random];
}

Although this works, the problem I'm having is finding the solution to when the user clicks on the image again. As there is only four possible numbers generated, I keep getting a repeating number from the var random method. I think I need a way to check the last number generated and if it's the same, it should try and generate a different number. This way there will be no repeating images. Hope this makes sense. Just so you know, I'm new to programming and only learning Javascript for the last 3 months. I think I may need a loop or another function inside this function, not sure.

Upvotes: 2

Views: 349

Answers (4)

Hogan
Hogan

Reputation: 165

I'm using the same function across the entire site so I'm using local storage with a window onload call to headerPic():

  const originalArr = ["image1.jpg", "image2.jpg", etc...];

  function headerPic() {
let headerImgArray = localStorage.getItem("headerList") ? JSON.parse(localStorage.getItem("headerList")) : originalArr;
if (headerImgArray.length < 1) {
    headerImgArray = originalArr;
}
const randomName = headerImgArray[Math.floor(Math.random() * headerImgArray.length)];
document.getElementById("headerImg").src = `imagesHeader/${randomName}`;
headerImgArray.splice(headerImgArray.indexOf(randomName), 1);
if (headerImgArray.length < 1) {
    headerImgArray = originalArr;
}
localStorage.setItem("headerList", JSON.stringify(headerImgArray));

}

Upvotes: 0

muZk
muZk

Reputation: 3038

You can filter your images, considering all items except the current background element, and take a random element of the result.

This is a example of how you can accomplish this:

function myAnimation(element) {

    var currentBackgroundImage = element.style.backgroundImage;

    var images = [
      "url(https://place-hold.it/100x100&text=1)",
      "url(https://place-hold.it/100x100&text=2)",
      "url(https://place-hold.it/100x100&text=3)",
      "url(https://place-hold.it/100x100&text=4)",
    ];

    var restOfImages = images.filter(function (image) {
      return image !== currentBackgroundImage;
    })

    var random = Math.floor(Math.random() * restOfImages.length);

    element.style.backgroundImage = restOfImages[random];
}

Another way, without filter:

function myAnimation(element) {

    var currentBackgroundImage = element.style.backgroundImage;

    var images = [
      "url(https://place-hold.it/100x100&text=1)",
      "url(https://place-hold.it/100x100&text=2)",
      "url(https://place-hold.it/100x100&text=3)",
      "url(https://place-hold.it/100x100&text=4)",
    ];

    var restOfImages = [];

    for(var i = 0; i < images.length; i++) {
      if (images[i] !== currentBackgroundImage) {
        restOfImages.push(images[i]);
      }
    }

    var random = Math.floor(Math.random() * restOfImages.length);
    element.style.backgroundImage = restOfImages[random];
}

And here is a working snipplet:

function myAnimation(element) {

    var currentBackgroundImage = element.style.backgroundImage;

    var images = [
      "url(https://place-hold.it/100x100&text=1)",
      "url(https://place-hold.it/100x100&text=2)",
      "url(https://place-hold.it/100x100&text=3)",
      "url(https://place-hold.it/100x100&text=4)",
    ];
    
    var restOfImages = images.filter(function (image) {
      return image !== currentBackgroundImage;
    })

    var random = Math.floor(Math.random() * restOfImages.length);

    element.style.backgroundImage = restOfImages[random];
}

var el = document.getElementById('container');

el.onclick= function() { myAnimation(el); };
#container{
  width: 100px;
  height: 100px;
  background-color: red;
}
<div id="container"></div>

Upvotes: 1

Meghan
Meghan

Reputation: 1261

You can repeatedly use Array.splice to remove a random element.

var images = [...
var random = Math.floor(Math.random() * 4);

element.style.backgroundImage = images.splice(random, 1)[0];

Upvotes: 0

abbas-ak
abbas-ak

Reputation: 642

I am checking prevNo with generated random number. If both are same, then call the function again. Else assign the random number to prevNo and load the image.

var prevNo = -1;
function myAnimation(element) {
    var images = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"];

    var random = Math.floor(Math.random() * 4);
    if( random == prevNo) { 
        myAnimation(element);
        return;
    } else {
        prevNo = random;
    }
    element.style.backgroundImage = images[random];
}

Upvotes: 1

Related Questions