657 lines
14 KiB
JavaScript
Executable File
657 lines
14 KiB
JavaScript
Executable File
/*! Superslides - v0.6.2 - 2013-07-10
|
|
* https://github.com/nicinabox/superslides
|
|
* Copyright (c) 2013 Nic Aitch; Licensed MIT */
|
|
(function(window, $) {
|
|
|
|
var Superslides, plugin = 'superslides';
|
|
|
|
Superslides = function(el, options) {
|
|
this.options = $.extend({
|
|
play: false,
|
|
animation_speed: 600,
|
|
animation_easing: 'swing',
|
|
animation: 'slide',
|
|
inherit_width_from: window,
|
|
inherit_height_from: window,
|
|
pagination: true,
|
|
hashchange: false,
|
|
scrollable: true,
|
|
elements: {
|
|
preserve: '.preserve',
|
|
nav: '.slides-navigation',
|
|
container: '.slides-container',
|
|
pagination: '.slides-pagination'
|
|
}
|
|
}, options);
|
|
|
|
var that = this,
|
|
$control = $('<div>', { "class": 'slides-control' }),
|
|
multiplier = 1;
|
|
|
|
this.$el = $(el);
|
|
this.$container = this.$el.find(this.options.elements.container);
|
|
|
|
// Private Methods
|
|
var initialize = function() {
|
|
multiplier = that._findMultiplier();
|
|
|
|
that.$el.on('click', that.options.elements.nav + " a", function(e) {
|
|
e.preventDefault();
|
|
|
|
that.stop();
|
|
if ($(this).hasClass('next')) {
|
|
that.animate('next', function() {
|
|
that.start();
|
|
});
|
|
} else {
|
|
that.animate('prev', function() {
|
|
that.start();
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on('keyup', function(e) {
|
|
if (e.keyCode === 37) {
|
|
that.animate('prev');
|
|
}
|
|
if (e.keyCode === 39) {
|
|
that.animate('next');
|
|
}
|
|
});
|
|
|
|
$(window).on('resize', function() {
|
|
setTimeout(function() {
|
|
var $children = that.$container.children();
|
|
|
|
that.width = that._findWidth();
|
|
that.height = that._findHeight();
|
|
|
|
$children.css({
|
|
width: that.width,
|
|
left: that.width
|
|
});
|
|
|
|
that.css.containers();
|
|
that.css.images();
|
|
}, 10);
|
|
});
|
|
|
|
$(window).on('hashchange', function() {
|
|
var hash = that._parseHash(), index;
|
|
|
|
if (hash && !isNaN(hash)) {
|
|
// Minus 1 here because we don't want the url
|
|
// to be zero-indexed
|
|
index = that._upcomingSlide(hash - 1);
|
|
|
|
} else {
|
|
index = that._upcomingSlide(hash);
|
|
}
|
|
|
|
if (index >= 0 && index !== that.current) {
|
|
that.animate(index);
|
|
}
|
|
});
|
|
|
|
that.pagination._events();
|
|
|
|
that.start();
|
|
return that;
|
|
};
|
|
|
|
var css = {
|
|
containers: function() {
|
|
if (that.init) {
|
|
that.$el.css({
|
|
height: that.height
|
|
});
|
|
|
|
that.$control.css({
|
|
width: that.width * multiplier,
|
|
left: -that.width
|
|
});
|
|
|
|
that.$container.css({
|
|
|
|
});
|
|
} else {
|
|
$('body').css({
|
|
margin: 0
|
|
});
|
|
|
|
that.$el.css({
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
width: '100%',
|
|
height: that.height
|
|
});
|
|
|
|
that.$control.css({
|
|
position: 'relative',
|
|
transform: 'translate3d(0)',
|
|
height: '100%',
|
|
width: that.width * multiplier,
|
|
left: -that.width
|
|
});
|
|
|
|
that.$container.css({
|
|
display: 'none',
|
|
margin: '0',
|
|
padding: '0',
|
|
listStyle: 'none',
|
|
position: 'relative',
|
|
height: '100%'
|
|
});
|
|
}
|
|
|
|
if (that.size() === 1) {
|
|
that.$el.find(that.options.elements.nav).hide();
|
|
}
|
|
},
|
|
images: function() {
|
|
var $images = that.$container.find('img')
|
|
.not(that.options.elements.preserve)
|
|
|
|
$images.removeAttr('width').removeAttr('height')
|
|
.css({
|
|
"-webkit-backface-visibility": 'hidden',
|
|
"-ms-interpolation-mode": 'bicubic',
|
|
"position": 'absolute',
|
|
"left": '0',
|
|
"top": '0',
|
|
"z-index": '-1',
|
|
"max-width": 'none'
|
|
});
|
|
|
|
$images.each(function() {
|
|
var image_aspect_ratio = that.image._aspectRatio(this),
|
|
image = this;
|
|
|
|
if (!$.data(this, 'processed')) {
|
|
var img = new Image();
|
|
img.onload = function() {
|
|
that.image._scale(image, image_aspect_ratio);
|
|
that.image._center(image, image_aspect_ratio);
|
|
$.data(image, 'processed', true);
|
|
};
|
|
img.src = this.src;
|
|
|
|
} else {
|
|
that.image._scale(image, image_aspect_ratio);
|
|
that.image._center(image, image_aspect_ratio);
|
|
}
|
|
});
|
|
},
|
|
children: function() {
|
|
var $children = that.$container.children();
|
|
|
|
if ($children.is('img')) {
|
|
$children.each(function() {
|
|
if ($(this).is('img')) {
|
|
$(this).wrap('<div>');
|
|
|
|
// move id attribute
|
|
var id = $(this).attr('id');
|
|
$(this).removeAttr('id');
|
|
$(this).parent().attr('id', id);
|
|
}
|
|
});
|
|
|
|
$children = that.$container.children();
|
|
}
|
|
|
|
if (!that.init) {
|
|
$children.css({
|
|
display: 'none',
|
|
left: that.width * 2
|
|
});
|
|
}
|
|
|
|
$children.css({
|
|
position: 'absolute',
|
|
overflow: 'hidden',
|
|
height: '100%',
|
|
width: that.width,
|
|
top: 0,
|
|
zIndex: 0
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
var fx = {
|
|
slide: function(orientation, complete) {
|
|
var $children = that.$container.children(),
|
|
$target = $children.eq(orientation.upcoming_slide);
|
|
|
|
$target.css({
|
|
left: orientation.upcoming_position,
|
|
display: 'block'
|
|
});
|
|
|
|
that.$control.animate({
|
|
left: orientation.offset
|
|
},
|
|
that.options.animation_speed,
|
|
that.options.animation_easing,
|
|
function() {
|
|
if (that.size() > 1) {
|
|
that.$control.css({
|
|
left: -that.width
|
|
});
|
|
|
|
$children.eq(orientation.upcoming_slide).css({
|
|
left: that.width,
|
|
zIndex: 2
|
|
});
|
|
|
|
if (orientation.outgoing_slide >= 0) {
|
|
$children.eq(orientation.outgoing_slide).css({
|
|
left: that.width,
|
|
display: 'none',
|
|
zIndex: 0
|
|
});
|
|
}
|
|
}
|
|
|
|
complete();
|
|
});
|
|
},
|
|
fade: function(orientation, complete) {
|
|
var that = this,
|
|
$children = that.$container.children(),
|
|
$outgoing = $children.eq(orientation.outgoing_slide),
|
|
$target = $children.eq(orientation.upcoming_slide);
|
|
|
|
$target.css({
|
|
left: this.width,
|
|
opacity: 1,
|
|
display: 'block'
|
|
});
|
|
|
|
if (orientation.outgoing_slide >= 0) {
|
|
$outgoing.animate({
|
|
opacity: 0
|
|
},
|
|
that.options.animation_speed,
|
|
that.options.animation_easing,
|
|
function() {
|
|
if (that.size() > 1) {
|
|
$children.eq(orientation.upcoming_slide).css({
|
|
zIndex: 2
|
|
});
|
|
|
|
if (orientation.outgoing_slide >= 0) {
|
|
$children.eq(orientation.outgoing_slide).css({
|
|
opacity: 1,
|
|
display: 'none',
|
|
zIndex: 0
|
|
});
|
|
}
|
|
}
|
|
|
|
complete();
|
|
});
|
|
} else {
|
|
$target.css({
|
|
zIndex: 2
|
|
});
|
|
complete();
|
|
}
|
|
}
|
|
};
|
|
|
|
fx = $.extend(fx, $.fn.superslides.fx);
|
|
|
|
var image = {
|
|
_centerY: function(image) {
|
|
var $img = $(image);
|
|
|
|
$img.css({
|
|
top: (that.height - $img.height()) / 2
|
|
});
|
|
},
|
|
_centerX: function(image) {
|
|
var $img = $(image);
|
|
|
|
$img.css({
|
|
left: (that.width - $img.width()) / 2
|
|
});
|
|
},
|
|
_center: function(image) {
|
|
that.image._centerX(image);
|
|
that.image._centerY(image);
|
|
},
|
|
_aspectRatio: function(image) {
|
|
if (!image.naturalHeight && !image.naturalWidth) {
|
|
var img = new Image();
|
|
img.src = image.src;
|
|
image.naturalHeight = img.height;
|
|
image.naturalWidth = img.width;
|
|
}
|
|
|
|
return image.naturalHeight / image.naturalWidth;
|
|
},
|
|
_scale: function(image, image_aspect_ratio) {
|
|
image_aspect_ratio = image_aspect_ratio || that.image._aspectRatio(image);
|
|
|
|
var container_aspect_ratio = that.height / that.width,
|
|
$img = $(image);
|
|
|
|
if (container_aspect_ratio > image_aspect_ratio) {
|
|
$img.css({
|
|
height: that.height,
|
|
width: that.height / image_aspect_ratio
|
|
});
|
|
|
|
} else {
|
|
$img.css({
|
|
height: that.width * image_aspect_ratio,
|
|
width: that.width
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
var pagination = {
|
|
_setCurrent: function(i) {
|
|
if (!that.$pagination) { return; }
|
|
|
|
var $pagination_children = that.$pagination.children();
|
|
|
|
$pagination_children.removeClass('current');
|
|
$pagination_children.eq(i)
|
|
.addClass('current');
|
|
},
|
|
_addItem: function(i) {
|
|
var slide_number = i + 1,
|
|
href = slide_number,
|
|
$slide = that.$container.children().eq(i),
|
|
slide_id = $slide.attr('id');
|
|
|
|
if (slide_id) {
|
|
href = slide_id;
|
|
}
|
|
|
|
var $item = $("<a>", {
|
|
'href': "#" + href,
|
|
'text': href
|
|
});
|
|
|
|
$item.appendTo(that.$pagination);
|
|
},
|
|
_setup: function() {
|
|
if (!that.options.pagination || that.size() === 1) { return; }
|
|
|
|
var $pagination = $("<nav>", {
|
|
'class': that.options.elements.pagination.replace(/^\./, '')
|
|
});
|
|
|
|
that.$pagination = $pagination.appendTo(that.$el);
|
|
|
|
for (var i = 0; i < that.size(); i++) {
|
|
that.pagination._addItem(i);
|
|
}
|
|
},
|
|
_events: function() {
|
|
that.$el.on('click', that.options.elements.pagination + ' a', function(e) {
|
|
e.preventDefault();
|
|
|
|
var hash = that._parseHash(this.hash),
|
|
index = that._upcomingSlide(hash - 1);
|
|
|
|
if (index !== that.current) {
|
|
that.animate(index, function() {
|
|
that.start();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
this.css = css;
|
|
this.image = image;
|
|
this.pagination = pagination;
|
|
this.fx = fx;
|
|
this.animation = this.fx[this.options.animation];
|
|
|
|
this.$control = this.$container.wrap($control).parent('.slides-control');
|
|
|
|
that._findPositions();
|
|
that.width = that._findWidth();
|
|
that.height = that._findHeight();
|
|
|
|
this.css.children();
|
|
this.css.containers();
|
|
this.css.images();
|
|
this.pagination._setup();
|
|
|
|
return initialize();
|
|
};
|
|
|
|
Superslides.prototype = {
|
|
_findWidth: function() {
|
|
return $(this.options.inherit_width_from).width();
|
|
},
|
|
_findHeight: function() {
|
|
return $(this.options.inherit_height_from).height();
|
|
},
|
|
|
|
_findMultiplier: function() {
|
|
return this.size() === 1 ? 1 : 3;
|
|
},
|
|
|
|
_upcomingSlide: function(direction) {
|
|
if ((/next/).test(direction)) {
|
|
return this._nextInDom();
|
|
|
|
} else if ((/prev/).test(direction)) {
|
|
return this._prevInDom();
|
|
|
|
} else if ((/\d/).test(direction)) {
|
|
return +direction;
|
|
|
|
} else if (direction && (/\w/).test(direction)) {
|
|
var index = this._findSlideById(direction);
|
|
if (index >= 0) {
|
|
return index;
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
} else {
|
|
return 0;
|
|
}
|
|
},
|
|
|
|
_findSlideById: function(id) {
|
|
return this.$container.find('#' + id).index();
|
|
},
|
|
|
|
_findPositions: function(current, thisRef) {
|
|
thisRef = thisRef || this;
|
|
|
|
if (current === undefined) {
|
|
current = -1;
|
|
}
|
|
|
|
thisRef.current = current;
|
|
thisRef.next = thisRef._nextInDom();
|
|
thisRef.prev = thisRef._prevInDom();
|
|
},
|
|
|
|
_nextInDom: function() {
|
|
var index = this.current + 1;
|
|
|
|
if (index === this.size()) {
|
|
index = 0;
|
|
}
|
|
|
|
return index;
|
|
},
|
|
|
|
_prevInDom: function() {
|
|
var index = this.current - 1;
|
|
|
|
if (index < 0) {
|
|
index = this.size() - 1;
|
|
}
|
|
|
|
return index;
|
|
},
|
|
|
|
_parseHash: function(hash) {
|
|
hash = hash || window.location.hash;
|
|
hash = hash.replace(/^#/, '');
|
|
|
|
if (hash && !isNaN(+hash)) {
|
|
hash = +hash;
|
|
}
|
|
|
|
return hash;
|
|
},
|
|
|
|
size: function() {
|
|
return this.$container.children().length;
|
|
},
|
|
|
|
destroy: function() {
|
|
return this.$el.removeData();
|
|
},
|
|
|
|
update: function() {
|
|
this.css.children();
|
|
this.css.containers();
|
|
this.css.images();
|
|
|
|
this.pagination._addItem(this.size())
|
|
|
|
this._findPositions(this.current);
|
|
this.$el.trigger('updated.slides');
|
|
},
|
|
|
|
stop: function() {
|
|
clearInterval(this.play_id);
|
|
delete this.play_id;
|
|
|
|
this.$el.trigger('stopped.slides');
|
|
},
|
|
|
|
start: function() {
|
|
var that = this;
|
|
|
|
if (that.options.hashchange) {
|
|
$(window).trigger('hashchange');
|
|
} else {
|
|
this.animate();
|
|
}
|
|
|
|
if (this.options.play) {
|
|
if (this.play_id) {
|
|
this.stop();
|
|
}
|
|
|
|
this.play_id = setInterval(function() {
|
|
that.animate();
|
|
}, this.options.play);
|
|
}
|
|
|
|
this.$el.trigger('started.slides');
|
|
},
|
|
|
|
animate: function(direction, userCallback) {
|
|
var that = this,
|
|
orientation = {};
|
|
|
|
if (this.animating) {
|
|
return;
|
|
}
|
|
|
|
this.animating = true;
|
|
|
|
if (direction === undefined) {
|
|
direction = 'next';
|
|
}
|
|
|
|
orientation.upcoming_slide = this._upcomingSlide(direction);
|
|
|
|
if (orientation.upcoming_slide >= this.size()) {
|
|
return;
|
|
}
|
|
|
|
orientation.outgoing_slide = this.current;
|
|
orientation.upcoming_position = this.width * 2;
|
|
orientation.offset = -orientation.upcoming_position;
|
|
|
|
if (direction === 'prev' || direction < orientation.outgoing_slide) {
|
|
orientation.upcoming_position = 0;
|
|
orientation.offset = 0;
|
|
}
|
|
|
|
if (that.size() > 1) {
|
|
that.pagination._setCurrent(orientation.upcoming_slide);
|
|
}
|
|
|
|
if (that.options.hashchange) {
|
|
var hash = orientation.upcoming_slide + 1,
|
|
id = that.$container.children(':eq(' + orientation.upcoming_slide + ')').attr('id');
|
|
|
|
if (id) {
|
|
window.location.hash = id;
|
|
} else {
|
|
window.location.hash = hash;
|
|
}
|
|
}
|
|
|
|
that.$el.trigger('animating.slides', [orientation]);
|
|
|
|
that.animation(orientation, function() {
|
|
that._findPositions(orientation.upcoming_slide, that);
|
|
|
|
if (typeof userCallback === 'function') {
|
|
userCallback();
|
|
}
|
|
|
|
that.animating = false;
|
|
that.$el.trigger('animated.slides');
|
|
|
|
if (!that.init) {
|
|
that.$el.trigger('init.slides');
|
|
that.init = true;
|
|
that.$container.fadeIn('fast');
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// jQuery plugin definition
|
|
|
|
$.fn[plugin] = function(option, args) {
|
|
var result = [];
|
|
|
|
this.each(function() {
|
|
var $this, data, options;
|
|
|
|
$this = $(this);
|
|
data = $this.data(plugin);
|
|
options = typeof option === 'object' && option;
|
|
|
|
if (!data) {
|
|
result = $this.data(plugin, (data = new Superslides(this, options)));
|
|
}
|
|
|
|
if (typeof option === "string") {
|
|
result = data[option];
|
|
if (typeof result === 'function') {
|
|
return result = result.call(data, args);
|
|
}
|
|
}
|
|
});
|
|
|
|
return result;
|
|
};
|
|
|
|
$.fn[plugin].fx = {};
|
|
|
|
})(this, jQuery);
|