Professional Documents
Culture Documents
/* Plugin Parameters
------------------------------------------------------------------
------------------------------- */
var pluginName = 'Kenburns',
defaults = {
images:[],
duration:400,
fadeSpeed:500,
scale:1,
ease3d:'cubic-bezier(.81, 0, .26, 1)',
onLoadingComplete:function(){},
onSlideComplete:function(){},
onListComplete:function(){},
getSlideIndex:function(){
return currentSlide;
}
};
this.init();
}
/* 1. Initialization
------------------------------------------------------------------
------------------------------- */
/**
* Init
* Initial setup - dermines width, height, and adds the loading
icon.
*/
Plugin.prototype.init = function () {
this.width = $(this.element).width();
this.height = $(this.element).height();
this.has3d = has3DTransforms();
for (i in list) {
imagesObj["image"+i] = {};
imagesObj["image"+i].loaded = false;
this.attachImage(list[i], "image"+i , i);
window.open(that.options.urls[currentSlide])
}
})
};
/**
* Attach image
* creates a wrapper div for the image along with the image tag.
The reason for the additional
* wrapper is that we are transitioning multiple properties at the
same time: scale, position, and
* opacity. But we want opacity to finish first. This function
also determines if the browser
* has 3d transform capabilities and initializes the starting CSS
values.
*/
Plugin.prototype.attachImage = function(url,alt_text,index) {
var that = this;
wrapper.html(img);
/**
* Resume
* Resume will continue the transition after the stalled image
loads
* it also fires the complete action when the series of images
finishes loading
*/
Plugin.prototype.resume = function(index){
//if the next image hasnt loaded yet, but the transition has
started,
// this will match the image index to the image holding the
transition.
// it will then resume the transition.
if(index == this.holdup) {
$('#status').html("");
$(this.element).find('.loader').hide();
this.startTransition(this.holdup);
}
//if the last image in the set has loaded, add the images in
order
if(this.checkLoadProgress() == true) {
//reset the opacities and z indexes except the last and
first images
$(this.element).find('.stalled').each(function(){
$(this).css({'opacity':1,'z-index':1});
$(this).removeClass('stalled');
});
//if any of the slides are not loaded, the set has not finished
loading.
Plugin.prototype.checkLoadProgress = function() {
var imagesLoaded = true;
for(i=0;i<this.maxSlides;i++){
if (imagesObj["image"+i].loaded == false){
imagesLoaded = false;
}
}
return imagesLoaded;
}
/**
* Wait
* Stops the transition interval, shows the loader and
* applies the stalled class to the visible image.
*/
Plugin.prototype.wait = function() {
clearInterval(this.interval);
$('#status').html("loading");
$(this.element).find('.loader').show();
/**
* startTransition
* Begins the Gallery Transition and tracks the current slide
* Also manages loading - if the interval encounters a slide
* that has not loaded, the transition pauses.
*/
Plugin.prototype.startTransition = function(start_index) {
var that = this;
currentSlide = start_index; //current slide
that.element.style.cursor = (that.options.urls &&
that.options.urls[currentSlide])? 'pointer' : 'auto'
that.doTransition();
this.interval = setInterval(function(){
//Advance the current slide
if(currentSlide < that.maxSlides-1){
currentSlide++;
}else {
currentSlide = 0;
}
that.element.style.cursor = (that.options.urls &&
that.options.urls[currentSlide])? 'pointer' : 'auto'
//Check if the next slide is loaded. If not, wait.
if(imagesObj["image"+currentSlide].loaded == false){
that.holdup = currentSlide;
that.wait();
},this.options.duration);
}
/**
* chooseCorner
* This function chooses a random start corner and a random end
corner
* that is different from the start. This gives a random direction
effect
* it returns coordinates used by the transition functions.
*/
Plugin.prototype.chooseCorner = function() {
var scale = this.options.scale;
var image = imagesObj["image"+currentSlide].element;
$(image).width(sw);
$(image).height(sh);
var w = $(this.element).width();
var h = $(this.element).height();
var corners = [
{x:0,y:0},
{x:1,y:0},
{x:0,y:1},
{x:1,y:1}
];
//
// console.log(coordinates.startX + " , "+coordinates.startY +
" , " +coordinates.endX + " , " +coordinates.endY);
return coordinates;
}
/**
* Transiton3D
* Transition3d Function works by setting the webkit and moz
translate3d properties. These
* are hardware accellerated and give a very smooth animation.
Since only one animation
* can be applied at a time, I wrapped the images in a div. The
shorter fade is applied to
* the parent, while the translation and scaling is applied to the
image.
*/
Plugin.prototype.transition3d = function () {
var that = this;
var scale = this.options.scale;
var image = imagesObj["image"+currentSlide].element;
var position = this.chooseCorner();
$(image).parent().animate({'opacity':1},that.options.fadeSpeed);
//set the end position and scale, which fires the transition
$(image).css({'-webkit-transform':'scale(1)
translate3d('+position.endX+'px,'+position.endY+'px,0)'});
$(image).css({'-moz-transform':'scale(1)
translate3d('+position.endX+'px,'+position.endY+'px,0)'});
this.transitionOut();
this.options.onSlideComplete();
}
/**
* Transition
* The regular JQuery animation function. Sets the currentSlide
initial scale and position to
* the value from chooseCorner before triggering the animation.
It starts the image moving to
* the new position, starts the fade on the wrapper, and delays
the fade out animation. Adding
* fadeSpeed to duration gave me a nice crossfade so the image
continues to move as it fades out
* rather than just stopping.
*/
Plugin.prototype.transition = function() {
var that = this;
var scale = this.options.scale;
var image = imagesObj["image"+currentSlide].element;
var sw = $(image).width();
var sh = $(image).height();
var position = this.chooseCorner();
$(image).css({'left':position.startX,'top':position.startY,'width':sw*
(scale),'height':sh*(scale)});
$(image).animate({'left':position.endX,'top':position.endY,'width':sw,
'height':sh}, that.options.duration + that.options.fadeSpeed);
$(image).parent().css({'opacity':0,'z-index':3});
$(image).parent().animate({'opacity':1},that.options.fadeSpeed);
this.transitionOut();
this.options.onSlideComplete();
}
Plugin.prototype.transitionOut = function() {
var that = this;
var image = imagesObj["image"+currentSlide].element;
$(image).parent().delay(that.options.duration).animate({'opacity':0},t
hat.options.fadeSpeed, function(){
$(this).css({'z-index':1});
});
}
/* 4. Utility Functions
------------------------------------------------------------------
------------------------------- */
/**
* has3DTransforms
* Tests the browser to determine support for Webkit and Moz
Transforms
* Creates an element, translates the element, and tests the
values. If the
* values return true, the browser supports 3D transformations.
*/
function has3DTransforms() {
var el = document.createElement('p'),
has3d,
transforms = {
'WebkitTransform':'-webkit-transform',
'MozTransform':'-moz-transform',
};
document.body.insertBefore(el, null);
document.body.removeChild(el);
return (has3d !== undefined && has3d.length > 0 && has3d !==
"none");
}
/**
* insertAt
* Utility function that inserts objects at a specific index
* Used to maintain the order of images as they are loaded and
* added to the DOM
*/
Plugin.prototype.insertAt = function (index, element) {
var lastIndex = $(this.element).children().length;
if (index < 0) {
index = Math.max(0, lastIndex + 1 + index);
}
var imgWrapper = $(this.element).append(element);
if (index < lastIndex) {
$(this.element).children().eq(index).before($(this.element).children()
.last());
}
}