Created
July 1, 2013 09:20
-
-
Save DaveRandom/5899497 to your computer and use it in GitHub Desktop.
Prototype for object which randomly displays a list of images with fading transitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jslint browser: true, plusplus: true, regexp: true, white: true */ | |
/** | |
* Prototype for object which randomly displays a list of images with fading transitions | |
* | |
* @package ImageRandomizer <https://gist.github.com/DaveRandom/5899497> | |
* @author Chris Wright <https://github.com/DaveRandom> | |
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom> | |
* @license http://www.opensource.org/licenses/mit-license.html MIT License | |
* @version 1.0.127 | |
*/ | |
var ImageRandomizer; | |
(function() | |
{ | |
"use strict"; | |
/** | |
* Get a random integer within the specified upper and lower bounds | |
* | |
* @param int max Upper bound | |
* @param int min Lower bound | |
* | |
* @return int | |
*/ | |
function rand(min, max) | |
{ | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
/** | |
* Constructor | |
* | |
* @param string frontContainerId DOM ID of the front container element | |
* @param string backContainerId DOM ID of the back container element | |
* @param string[] images List of image URLs to show in the rotation | |
* | |
* @throws Error When one or more of the arguments is invalid | |
*/ | |
ImageRandomizer = function(frontContainerId, backContainerId, images) | |
{ | |
var frontContainer, backContainer; | |
if (frontContainerId === undefined) { | |
throw new Error('Front container ID is not defined'); | |
} | |
if (backContainerId === undefined) { | |
throw new Error('Front container ID is not defined'); | |
} | |
if (images === undefined || !(images instanceof Array)) { | |
throw new Error('Images array is invalid'); | |
} | |
frontContainer = document.getElementById(frontContainerId); | |
if (!frontContainer) { | |
throw new Error('Front container ID is not invalid'); | |
} | |
backContainer = document.getElementById(backContainerId); | |
if (!backContainer) { | |
throw new Error('Back container ID is not invalid'); | |
} | |
this.frontContainer = frontContainer; | |
this.backContainer = backContainer; | |
this.imageList = images; | |
}; | |
/** | |
* @var HTMLElement Reference to the front container element | |
*/ | |
ImageRandomizer.prototype.frontContainer = null; | |
/** | |
* @var HTMLElement Reference to the back container element | |
*/ | |
ImageRandomizer.prototype.backContainer = null; | |
/** | |
* @var string[] List of image URLs to show in the rotation | |
*/ | |
ImageRandomizer.prototype.imageList = null; | |
/** | |
* @var int How long to display each image (in milliseconds) | |
*/ | |
ImageRandomizer.prototype.displayTime = 5000; | |
/** | |
* @var int How long the transition animation lasts (in milliseconds) | |
*/ | |
ImageRandomizer.prototype.transitionTime = 1000; | |
/** | |
* @var int Interval between animation frames (in milliseconds) | |
*/ | |
ImageRandomizer.prototype.frameInterval = 33; | |
/** | |
* @var int Identifier for the active animation timeout | |
*/ | |
ImageRandomizer.prototype.timeout = null; | |
/** | |
* @var number Timestamp at which the current animation sequence began | |
*/ | |
ImageRandomizer.prototype.animStart = null; | |
/** | |
* Get the URL of the image currently attached to a display container | |
* | |
* @param HTMLElement el Display container to inspect | |
* | |
* @return string | |
*/ | |
ImageRandomizer.prototype.getCurrentImagePath = function(el) | |
{ | |
return el.style.backgroundImage.match(/url\s*\(\s*([^)]+)\s*\)/)[1]; | |
}; | |
/** | |
* Start the rotation | |
* | |
* @param int displayTime (optional) How long to display each image (in milliseconds) | |
* @param int transitionTime (optional) How long the transition animation lasts (in milliseconds) | |
*/ | |
ImageRandomizer.prototype.start = function(displayTime, transitionTime) | |
{ | |
var that = this; | |
if (this.timeout !== null) { | |
return; | |
} | |
if (displayTime !== undefined) { | |
this.displayTime = parseInt(displayTime, 10); | |
} | |
if (transitionTime !== undefined) { | |
this.transitionTime = parseInt(transitionTime, 10); | |
} | |
this.timeout = setTimeout(function() { | |
that.showBack(); | |
}, this.displayTime); | |
}; | |
/** | |
* Stop the rotation | |
* | |
* @param int displayTime (optional) How long to display each image (in milliseconds) | |
* @param int transitionTime (optional) How long the transition animation lasts (in milliseconds) | |
*/ | |
ImageRandomizer.prototype.stop = function() | |
{ | |
if (this.timeout !== null) { | |
clearTimeout(this.timeout); | |
this.timeout = null; | |
} | |
}; | |
/** | |
* Get a number between representing the progress through the current animation cycle | |
* | |
* @return float A number between 0 and 1, where 0 is the start and 1 is the end | |
*/ | |
ImageRandomizer.prototype.getAnimProgress = function() | |
{ | |
if (this.animStart === null) { | |
this.animStart = (new Date()).getTime(); | |
} | |
return ((new Date()).getTime() - this.animStart) / this.transitionTime; | |
}; | |
/** | |
* Process a frame for a transition to the back container | |
*/ | |
ImageRandomizer.prototype.showBack = function() | |
{ | |
var progress, that = this; | |
progress = this.getAnimProgress(); | |
if (progress < 1) { | |
this.frontContainer.style.opacity = 1 - progress; | |
this.frontContainer.style.filter = 'alpha(opacity=' + ((1 - progress) * 100) + ')'; | |
setTimeout(function() { | |
that.showBack(); | |
}, this.frameInterval); | |
} else { | |
this.animStart = null; | |
this.frontContainer.style.opacity = 0; | |
this.frontContainer.style.filter = 'alpha(opacity=0)'; | |
this.frontContainer.style.backgroundImage = 'url(' + this.getNewImage(this.getCurrentImagePath(this.backContainer)) + ')'; | |
setTimeout(function() { | |
that.showFront(); | |
}, this.displayTime); | |
} | |
}; | |
/** | |
* Process a frame for a transition to the front container | |
*/ | |
ImageRandomizer.prototype.showFront = function() | |
{ | |
var progress, that = this; | |
progress = this.getAnimProgress(); | |
if (progress < 1) { | |
this.frontContainer.style.opacity = progress; | |
this.frontContainer.style.filter = 'alpha(opacity=' + (progress * 100) + ')'; | |
setTimeout(function() { | |
that.showFront(); | |
}, this.frameInterval); | |
} else { | |
this.animStart = null; | |
this.frontContainer.style.opacity = 100; | |
this.frontContainer.style.filter = 'alpha(opacity=100)'; | |
this.backContainer.style.backgroundImage = 'url(' + this.getNewImage(this.getCurrentImagePath(this.frontContainer)) + ')'; | |
setTimeout(function() { | |
that.showBack(); | |
}, this.displayTime); | |
} | |
}; | |
/** | |
* Get a new random image URL from the rotation list | |
* | |
* @param string not URL to exclude from the possible results | |
* | |
* @return string | |
*/ | |
ImageRandomizer.prototype.getNewImage = function(not) | |
{ | |
var i, l = this.imageList.length, a = []; | |
for (i = 0; i < l; i++) { | |
if (this.imageList[i] !== not.slice(this.imageList[i].length * -1)) { | |
a.push(this.imageList[i]); | |
} | |
} | |
return a[rand(0, a.length - 1)]; | |
}; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment