0

The code below randomizes image locations on a webpage. Is there any way I could alter the code to prevent the script from using the same image more than once? As of now, it will sometimes reuse the same photo multiple times on the page load, and I would like to prevent this so that only one of each photo gets used.

In other words, is there any way to randomly populate image locations on the webpage without repeating the same image but also using them all?

Let me know if you can help. :)

const imgPoss = [];

let maxX, maxY;

function placeImg() {
    const NUM_OF_IMAGES = 23; // set this to however images you have in the directory.
    const START_OF_IMAGES = 1;
        const randImg = Math.round(Math.random() * NUM_OF_IMAGES + START_OF_IMAGES);
        const imgSrc = 'https://elimcgehee.github.io/staticimages/gallery/' + randImg.toString() + '.png';

    const {random: r} = Math;  
    const x = r() * maxX;
    const y = r() * maxY;
    
    if(!isOverlap(x,y)) {
        var link = `<img class="random" style="left: ${x}px; top: ${y}px;" src="${imgSrc}" />`;
        var bodyHtml = document.body.innerHTML;
        document.body.innerHTML = bodyHtml + link;
        
        imgPoss.push({x, y}); // record all img positions
    }
}

function isOverlap(x, y) { // return true if overlapping
    const img = {x: 128, y:160};
    
    for(const imgPos of imgPoss) {
        if( x>imgPos.x-img.x && x<imgPos.x+img.x &&
            y>imgPos.y-img.y && y<imgPos.y+img.y ) return true;
    }
    return false;
}

onload = function() {
    maxX = innerWidth - 128;
    maxY = innerHeight - 160;
    setInterval(placeImg, 10);
}

onresize = function() {
    maxX = innerWidth - 128;
    maxY = innerHeight - 160;
}
  • maybe you can just use the images sequentially since you randomize their position anyway? – IT goldman Nov 07 '22 at 23:25
  • Does this answer your question? [Generating non-repeating random numbers in JS](https://stackoverflow.com/questions/18806210/generating-non-repeating-random-numbers-in-js) and [Random Image Display, Without Repeat, with Javascript](https://stackoverflow.com/questions/20496746/random-image-display-without-repeat-with-javascript) – kmoser Nov 07 '22 at 23:58
  • @ITgoldman Do you know how I could go about doing this? – Eli McGehee Nov 11 '22 at 19:15

1 Answers1

0

At first I was going to suggest just for loop over the images since their position is randomized anyway. But here's a more general approach: a function that creates a function that returns a number from a range randomly and without repetitions. May you find it useful.

Explanation: it shuffles an array of the required numbers in range, then returns a function that will pop a value from that array until all values exhausted.

function generateUniqueRandomizerOverRange(a, b) {

  // modern fisher yates shuffle
  function shuffle(arr) {
    var n = arr.length;
    for (var i = n - 1; i > 0; i--) {
      var j = Math.floor(Math.random() * (i + 1));
      var tmp = arr[i];
      arr[i] = arr[j];
      arr[j] = tmp;
    }
    return arr;
  }

  var arr = [];
  for (var i = a; i <= b; i++) {
    arr.push(i)
  }

  arr = shuffle(arr)

  return function () {
    if (arr.length) {
      return arr.pop();
    }
    return null;
  }
}


// usage:
var uniqueRandomizer = generateUniqueRandomizerOverRange(1, 23);
for (var i = 0; i < 23; i++) {
  console.log(uniqueRandomizer())
}
IT goldman
  • 14,885
  • 2
  • 14
  • 28