var timer1, timer2, startTimer1, startTimer2; var startDelay = 500; var fadeTime = 400; var slideDelay = 600; function setupSlideshow(that, numOfScenes) { // this function runs only once, it sets up all the events (mouseenter, mouseleave) // then initiates the slideshow and uses a flag to remember that it's been called var self = $(that); var flag = self.retrieve('slideshow:setup', false); if (flag) return false; // set default value of numOfScenes if not specified numOfScenes = $pick(numOfScenes, 5); // flag was not set, so setup the slideshow /* Algorithm 1 - duplicate the existing image and hide the copy 2 - run a loop that 2a - fades in and out the 2nd image 2b - "increments" the sources of image1 and image2 to the next scenes 2c - loops the scene numbers using the numOfScenes limit 2d - repeat loops until mouseleave */ // 1 - duplicate 1st scene thumb, set new source for the copy, hide it and attach to DOM var image1 = self.getElement('img.ct'); var image2 = image1.clone(); image2.src = incSceneNum(image1.src, numOfScenes); image2.setStyle('opacity',0).injectAfter(image1); startTimer1 = setTimeout( function(){ playImages(image1, image2, numOfScenes); }, startDelay ); self.addEvent('mouseenter', function(e){ startTimer2 = setTimeout( function(){ playImages(image1, image2, numOfScenes); }, startDelay ); }); self.addEvent('mouseleave', function(e){ clearTimeout(startTimer1); clearTimeout(startTimer2); clearTimeout(timer2); }); // once the setup is done set the flag to true so function doesn't do all this again self.store('slideshow:setup', true); return true; } // takes scene path string and if 'num' not specified // returns path to the next scene in sequence with '0' padding // if num specified then it builds new path using the 'num' number // limit used to loop the sequence of numbers /* Nasty overload - if 'limit' is array then loop through array and use it to increment numbers */ function incSceneNum(path, limit, num) { // "split" the string into plainPath and numberExtension var plainPath = path.slice(0, -6); var numberExtension = path.slice(-6); // further split number and extension var numExt = numberExtension.split("."); var nextNum; // if limit is just a number then proceed as usual if ($type(limit)=='number') { // if 'num' is specified we're good to go, otherwise, convert extracted number to integer var numInt = numExt[0].toInt(); var nextNum = num ? num : (numInt==limit ? 1 : numInt+1); } else if ($type(limit)=='array') { // shift the array to get next number (pops the 1st element) nextNum = limit.shift(); // push that number back into the array, thus looping them limit.push(nextNum); } // pad nextNum to '0x' if needed (converts it to string) nextNum = nextNum < 10 ? '0'+nextNum : nextNum; // finally output the string for next scene in sequence return plainPath + nextNum + "." + numExt[1]; } function playImages(img1, img2, sceneLimit) { var fadeFx = new Fx.Tween(img2, {property:'opacity', duration:fadeTime, fps:30}); // if img2 opacity is 0, fade it in, else fade it out // once fade in/out done, switch up the source of the hidden image if (img2.getStyle('opacity')==0) { fadeFx.start(0, 1); timer1 = setTimeout( function(){ img1.src = incSceneNum(img2.src, sceneLimit); }, fadeTime ); } else { fadeFx.start(1,0); timer1 = setTimeout( function(){ img2.src = incSceneNum(img1.src, sceneLimit); }, fadeTime ); } // now take into account fadeTime and slideDelay and set timeout for recursive call timer2 = setTimeout( function(){ clearTimeout( timer2 ); playImages(img1, img2, sceneLimit); }, fadeTime + slideDelay ); }