PDA

View Full Version : Fade-in Slideshow: random display of images how-to



orbit1877
04-23-2005, 08:20 AM
Script: Fade-in Slideshow
http://www.dynamicdrive.com/dynamicindex14/fadeinslideshow.htm

I am using the excellent fade in slideshow but would like the script to display my images in a random order, that is, once an image is displayed it should then randomly pick one of the other images to display next. Can this be achieved easily by modifying the script? How? Thanks for your help in advance! cheers

mwinter
04-24-2005, 05:56 PM
randimageindex=parseInt(Math.random()*fadeimages.length)Using the parseInt function to truncate a floating point number is very inefficient. The number would first have to be converted to a string, then parsed as an integer, and finally being returned as a number. Use Math.floor instead.


while (randimageindex==nextimageindex){
randimageindex=parseInt(Math.random()*fadeimages.length)
if (randimageindex!==nextimageindex)
break
}Why break out of the loop in the way you're attempting to do so? It would happen automatically anyway when the expression is evaluated at the top of the loop.


var randimageindex;

do {
randimageindex = Math.floor((Math.random() % 1) * fadeimages.length);
} while(randimageindex == nextimageindex);

/* or:
*
* while(nextimageindex == (randimageindex = Math.floor((Math.random() % 1) * fadeimages.length)));
*/

nextimageindex = randimageindex;The OP can ignore this bit...


to keep the code from using more stack space than it needs, [declare randimageindex local]Though the declaration is a good idea, it isn't for the reasons you cite. In the absence of the declaration, the variable would be created as a property of the global object; it wouldn't take any "stack" space at all. However, the creation of globals should always be avoided if possible as that tends to lead to more reusable, more robust code. With the declaration, the variable would be created as a property of the function object's variable object.

Mike

jscheuer1
04-24-2005, 07:41 PM
I deleted my message that Mike is commenting on above. Upon further testing it didn't work with more than three images. If I figure out the problem, which has nothing to do with Mike's comments, as far as I can tell, I will post a working randomizer.

jscheuer1
04-24-2005, 08:20 PM
Still suffering from Mike's problems, here is the new code, same as the old code, it was my testing that was flawed, the code works fine.

Just after this line:


function fadepic(){add this line:


var randimageindexReplace this line:


nextimageindex=(nextimageindex<fadeimages.length-1)? nextimageindex+1 : 0with these lines:


randimageindex=parseInt(Math.random()*fadeimages.length)
while (randimageindex==nextimageindex){
randimageindex=parseInt(Math.random()*fadeimages.length)
if (randimageindex!==nextimageindex)
break
}
nextimageindex=randimageindex

orbit1877
04-25-2005, 01:12 AM
Hi

thanks to both of you for your help, this is excellent. I have used this bit now and it seems to work fine. It looks like the first and second image that is displayed is always the same, but then it seems to randomize subsequent images.

Question: What is the difference between the two versions of WHILE conditions?



var randimageindex;

do {
randimageindex = Math.floor((Math.random() % 1) * fadeimages.length);
} while(randimageindex == nextimageindex);

/* or:
*
* while(nextimageindex == (randimageindex = Math.floor((Math.random() % 1) * fadeimages.length)));
*/

nextimageindex = randimageindex;

mwinter
04-25-2005, 06:10 PM
It looks like the first and second image that is displayed is always the same, but then it seems to randomize subsequent images.The script initialises using hard-coded indicies. You could randomise these, but I think there's a better solution which wouldn't require modification of the script, per se: shuffling. Rather than randomly choosing values from a set, randomise the set itself. You could either do it once at the start, or repeatedly.

The three functions below define a two new methods for array objects: shuffle and swap. The former randomly orders the elements of that object, and the latter is just a utility function that swaps two elements.


function random(n) {
return Math.floor((Math.random() % 1) * n);
}

Array.prototype.shuffle = function() {var i = this.length;
while(i--) {this.swap(i, random(i + 1));}
};
Array.prototype.swap = function(x, y) {
var t = this[x]; this[x] = this[y]; this[y] = t;
};After you've defined the fadeimages array using the original, unmodified script, call fadeimages.shuffle() and you should always have a randomised sequence.


Question: What is the difference between the two versions of WHILE conditions?Both statements are functionally equivalent. I prefer the do..while version as it's clearer, but as I was replacing John's while statement I thought I'd show an equivalent.

If you use the shuffle approach above, neither are necessary.

Mike

orbit1877
04-26-2005, 08:42 AM
great idea! perfect! thanks heaps :-)

ddadmin
04-26-2005, 08:29 PM
Great discussion. I had planned on updating Fade In Slideshow with a randomize display order feature, but decided to put it off until next month since I got side tracked. But here's the preview of the code, which seems very similar to Mwinter's:


////NO need to edit beyond here/////////////

var randomizeimage="yes" //randomize dislay order of images? "yes" or "no"

function shuffleit(){
return Math.floor((Math.random()*fadeimages.length-1))
}

if (randomizeimage=="yes")
fadeimages.sort(shuffleit)
As you can see, simply add the code right below the "////No need to edit///" divider of the script. Function shuffleit() is key here.

mwinter
04-26-2005, 09:20 PM
function shuffleit(){
return Math.floor((Math.random()*fadeimages.length-1))
}

if (randomizeimage=="yes")
fadeimages.sort(shuffleit)That's not necessarily a good approach. It should shuffle the array, but it may not. Before I explain, could I make a quick suggestion? Rather than perform a string comparison when choosing to sort, why not use booleans instead. I think


var randomiseImage = false; /* Set to true to randomise the image order. */

/* ... */

if(randomiseImage) {/* ... */}should be quite understandable to anyone: experienced programmer or not. I also think it's better use of the language.

Now, back to the point. The sort method expects three sorts of values from the comparison function: numbers that are either less than, greater than, or equal to zero. The shuffleit function above only returns the latter two. A better approach would be:


fadeimages.sort(
function() {return 0.5 - Math.random();}
);The comparison function would now randomly return a value between -0.5 (exclusive) and 0.5 (inclusive), which might have a better chance of creating a mess. :)

But. :rolleyes: Taking the sort method approach might not work. It could depend on what sort algorithm is implemented by the host. Whilst it's shorter - both in code length and execution time - it might produce sub-standard results.

Mike

ddadmin
04-27-2005, 12:34 PM
Hi Mwinter:


Before I explain, could I make a quick suggestion? Rather than perform a string comparison when choosing to sort, why not use booleans instead.
I agree Booleans is a better approach. However I used a string instead just in case I needed it to support values other than "yes" or "no", such as "backwards" as far as the sequence of the images. But I agree Boolean would be a better approach in general.

Thanks for the info on the sort algorithm. I haven't really given my own code too much thought nor testing apart from seeing that it worked, so I'll take your word that there are some problems with it. I'll try and dissect your code some more as soon as I have the time. Thanks for that. :)

mwinter
04-27-2005, 08:50 PM
Hi Mwinter:Mike will do nicely, thank you. :p


However I used a string instead just in case I needed it to support values other than "yes" or "no", such as "backwards" as far as the sequence of the images.But then the variable should be named order, or something similar. :D


I'll try and dissect your code some more as soon as I have the time.There isn't really that much to it.


Array.prototype.shuffle = function() {
/* Initialise the index variable so that we start
* at the end of the array.
*/
var i = this.length;

/* Loop through each element, back-to-front. */
while(i--) {
/* At any position i within the array, there will
* be i more elements before we reach the end:
*
* [0, 1, 2, 3, 4]
*
* At the 3rd element, there are three more
* elements: 2, 1, and 0.
* We want to randomly place one of these elements
* at the current location, so we should generate a
* random number in the range [0,i) (that is,
* random(i)). We can do this by swapping the
* current element and the one at the generated
* index.
* However, to be truly random, the current element
* should have a chance of remaining where it is,
* so we expand the range accordingly.
*/
this.swap(i, random(i + 1));
}
};I don't think it's necessary to describe the random helper function, nor the swap method (though someone correct me if I'm wrong).

Mike

webwizard
11-19-2007, 02:41 PM
A better approach would be:


fadeimages.sort(
function() {return 0.5 - Math.random();}
);

This old post was just the ticket. Mikes advise worked great!

jscheuer1
11-19-2007, 04:37 PM
This old post was just the ticket. Mikes advise worked great!

That bit of code has been included in the script for quite some time now and can be activated with the 'R' argument.