Skip to content

Instantly share code, notes, and snippets.

@DaveRandom
Created July 1, 2013 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaveRandom/5899497 to your computer and use it in GitHub Desktop.
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
/*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