I'm trying to position images within a banner div on a web page. The images need to be positioned 'randomly' along the x axis (using the CSS left
property), so they don't always appear the same when the page is loaded. I have the following script to do this (it also sets a random delay so the images appear in a different temporal order each time:
for (var i = 1; i <= 5; i++) {
var delay = Math.floor(Math.random() * 800) + 1;
var xPos = Math.floor(Math.random() * 900) + 1;
$('#item'+i).css('left',xPos+'px').delay(delay).animate({ top: 18 }, { duration: 1000, easing: 'easeOutBounce' });
}
However, the problem is that there's very often too much overlap with the images and they're hidden behind one another. So I'd like to skew the randomness so that there's at least 100px difference between all of the xPos variables. This should give me a random-looking appearance but keeping the items mostly visible too.
There must be a word to describe this kind of thing but having searched I just can't find anything useful to indicate how to achieve it.
Can anyone point me in the right direction here?
Many thanks.
EDIT:
Okay, so having a go at rolling my own functions to do this. I think I'm almost there. What I'm doing is creating an initial random number and adding this to an array, then looping through each of the 5 items and generating another random number, then comparing this to make sure it's more than 100 different to anything currently in the array.
The code is like this (not all of my variables are being used currently - it's a work in progress!):
function randomImagePlacement() {
var containerWidth = 940; // Width of container element
var itemWidth = 267; // Width of item (taking into account rotation)
var minX = 0; // Minimum left position of an item
var maxX = containerWidth - itemWidth; // Maximum left position of an item
var minSeparation = 100; // Minimum number of pixels of separation between items
var numberOfItems = 5; // Total number of items
var randomNumbers = []; // Array 'container' to hold random numbers
for (var i = 1; i <= numberOfItems; i++) {
if (i == 1) {
var firstRandomNumber = Math.floor(Math.random() * 700) + 1;
randomNumbers.push(firstRandomNumber);
console.log('First random number: ' + firstRandomNumber);
} else {
var newRandomNumber = Math.floor(Math.random() * 700) + 1;
/*
This if/else block works okay but it doesn't keep checking differences until the criteria is met
if (checkDiff(newRandomNumber, randomNumbers)) {
console.log('New number (' + newRandomNumber + ') sufficiently different enough');
randomNumbers.push(newRandomNumber);
} else {
console.log('New number (' + newRandomNumber + ') NOT sufficiently different enough');
}
*/
/* This do/while block is my attempt at trying to run the check diff function until the criteria is met, but it just results in the browser crashing */
do {
randomNumbers.push(newRandomNumber);
} while (checkDiff(newRandomNumber, randomNumbers) == true);
}
}
for (var i = 0; i < randomNumbers.length; i++) {
console.log('From final array: ' + randomNumbers[i]);
}
}
function checkDiff(newRandomNumber, currentArray) {
console.log('newRandomNumber = ' + newRandomNumber);
var proximityMatch = false;
for (var i = 0; i < currentArray.length; i++) {
console.log('Diff between ' + currentArray[i] + ' and ' + newRandomNumber + ' = ' + Math.abs(currentArray[i] - newRandomNumber));
if (Math.abs(currentArray[i] - newRandomNumber) > 100) {
proximityMatch = true;
}
}
if (proximityMatch == true) {
return true;
} else {
return false;
}
}
randomImagePlacement();
Basically where it's failing is in the do/while loop above. I'm not sure of the correct way to do something like this, but I basically need to say "Keep running the checkDiff function until it returns true; when it does return true add the newRandomNumber to the array; if it doesn't return true run it again".
Can anyone help me out on this?
Many thanks!
A possible way you could approach this is:
item0.x = //random number
item1.x = item0.x+item0.width + 100 + (random number)
item2.x = item1.x+item1.width + 100 + (random number)
etc.
UPDATE
Sorry, I didn't realize you needed that comparison across all generated values. This will work:
The way I'd accomplish this would be to:
An example: