Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 188 additions & 107 deletions lib/jquery.tinycarousel.js
Original file line number Diff line number Diff line change
@@ -1,210 +1,291 @@
;(function (factory)
{
if (typeof define === 'function' && define.amd)
{
;(function(factory) {
if(typeof define === 'function' && define.amd) {
define(['jquery'], factory);
}
else if (typeof exports === 'object')
{
factory(require('jquery'));
else if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
}
else
{
else {
factory(jQuery);
}
}
(function ($)
{
(function($) {
var pluginName = "tinycarousel"
, defaults =
{
start: 0 // The starting slide
, axis: "x" // vertical or horizontal scroller? ( x || y ).
, buttons: true // show left and right navigation buttons.
, bullets: false // is there a page number navigation present?
, interval: false // move to another block on intervals.
, intervalTime: 3000 // interval time in milliseconds.
, animation: true // false is instant, true is animate.
, animationTime: 1000 // how fast must the animation move in ms?
, infinite: true // infinite carousel.
start: 0
, axis: "x"
, buttons: true
, bullets: false
, interval: false
, intervalTime: 3000
, animation: true
, animationTime: 1000
, infinite: true
, moveNumber: 1
}
;

function Plugin($container, options)
{
this.options = $.extend({}, defaults, options);
function Plugin($container, options) {
/**
* The options of the carousel extend with the defaults.
*
* @property options
* @type Object
* @default defaults
*/
this.options = $.extend({}, defaults, options);

/**
* @property _defaults
* @type Object
* @private
* @default defaults
*/
this._defaults = defaults;
this._name = pluginName;

var self = this
/**
* @property _name
* @type String
* @private
* @final
* @default 'tinycarousel'
*/
this._name = pluginName;

var self = this
, $viewport = $container.find(".viewport:first")
, $overview = $container.find(".overview:first")
, $slides = 0
, $next = $container.find(".next:first")
, $prev = $container.find(".prev:first")
, $bullets = $container.find(".bullet")

, viewportSize = 0
, contentStyle = {}
, slidesVisible = 0
, slideSize = 0
, slideIndex = 0

, isHorizontal = this.options.axis === 'x'
, sizeLabel = isHorizontal ? "Width" : "Height"
, posiLabel = isHorizontal ? "left" : "top"
, $slides = null
, $next = $container.find(".next:first")
, $prev = $container.find(".prev:first")
, $bullets = $container.find(".bullet")

, viewportSize = 0
, contentStyle = {}
, slidesVisible = 0
, slideSize = 0
, slideIndex = 0

, isHorizontal = this.options.axis === 'x'
, sizeLabel = isHorizontal ? "Width" : "Height"
, posiLabel = isHorizontal ? "left" : "top"
, intervalTimer = null
;

/**
* The index of the current slide.
*
* @property slideCurrent
* @type Number
* @default 0
*/
this.slideCurrent = 0;
this.slidesTotal = 0;

function initialize()
{
/**
* The number of slides the carousel is currently aware of.
*
* @property slidesTotal
* @type Number
* @default 0
*/
this.slidesTotal = 0;

/**
* If the interval is running the value will be true.
*
* @property intervalActive
* @type Boolean
* @default false
*/
this.intervalActive = false;

/**
* @method _initialize
* @private
*/
function _initialize() {
self.update();
self.move(self.slideCurrent);

setEvents();
_setEvents();

return self;
}

this.update = function()
{
/**
* You can use this method to add new slides on the fly. Or to let the carousel recalculate itself.
*
* @method update
* @chainable
*/
this.update = function() {
$overview.find(".mirrored").remove();

$slides = $overview.children();
viewportSize = $viewport[0]["offset" + sizeLabel];
slideSize = $slides.first()["outer" + sizeLabel](true);
self.slidesTotal = $slides.length;
$slides = $overview.children();
viewportSize = $viewport[0]["offset" + sizeLabel];
slideSize = $slides.first()["outer" + sizeLabel](true);
self.slidesTotal = $slides.length;
self.slideCurrent = self.options.start || 0;
slidesVisible = Math.ceil(viewportSize / slideSize);
slidesVisible = Math.ceil(viewportSize / slideSize);
self.moveNumber = (self.options.moveNumber > self.slidesTotal) ? self.slidesTotal : self.options.moveNumber;

$overview.append($slides.slice(0, slidesVisible).clone().addClass("mirrored"));
$overview.css(sizeLabel.toLowerCase(), slideSize * (self.slidesTotal + slidesVisible));
$overview.append($slides.slice(0, self.slidesTotal).clone().addClass("mirrored"));
$overview.append($slides.slice(0, self.slidesTotal).clone().addClass("mirrored"));
$overview.css(sizeLabel.toLowerCase(), slideSize * self.slidesTotal * 3);

setButtons();
_setButtons();

return self;
};

function setEvents()
{
if(self.options.buttons)
{
$prev.click(function()
{
self.move(--slideIndex);
/**
* @method _setEvents
* @private
*/
function _setEvents() {
if(self.options.buttons) {
$prev.click(function() {
self.move(slideIndex - self.moveNumber);

return false;
});

$next.click(function()
{
self.move(++slideIndex);
$next.click(function() {
self.move(slideIndex + self.moveNumber);

return false;
});
}

$(window).resize(self.update);

if(self.options.bullets)
{
$container.on("click", ".bullet", function()
{
if(self.options.bullets) {
$container.on("click", ".bullet", function() {
self.move(slideIndex = +$(this).attr("data-slide"));

return false;
});
}
}

this.start = function()
{
if(self.options.interval)
{

/**
* If the interval is stoped start it.
*
* @method start
* @chainable
*/
this.start = function() {
if(self.options.interval) {
clearTimeout(intervalTimer);

intervalTimer = setTimeout(function()
{
self.move(++slideIndex);
self.intervalActive = true;

intervalTimer = setTimeout(function() {
self.move(slideIndex + self.moveNumber);

}, self.options.intervalTime);
}

return self;
};

this.stop = function()
{
/**
* If the interval is running stop it.
*
* @method start
* @chainable
*/
this.stop = function() {
clearTimeout(intervalTimer);

self.intervalActive = false;

return self;
};

this.move = function(index)
{
slideIndex = index;
/**
* Move to a specific slide.
*
* @method move
* @chainable
* @param {Number} [index] The slide to move to.
*/
this.move = function(index) {
slideIndex = isNaN(index) ? self.slideCurrent : index;
self.slideCurrent = slideIndex % self.slidesTotal;

if(slideIndex < 0)
{
self.slideCurrent = slideIndex = self.slidesTotal - 1;
$overview.css(posiLabel, -(self.slidesTotal) * slideSize);
if(slideIndex < 0) {
self.slideCurrent = slideIndex = index + self.slidesTotal;
$overview.css(posiLabel, -(slideIndex + self.moveNumber) * slideSize);
}

if(slideIndex > self.slidesTotal)
{
self.slideCurrent = slideIndex = 1;
$overview.css(posiLabel, 0);
if(slideIndex > (self.slidesTotal*2)) {
self.slideCurrent = slideIndex = index - self.slidesTotal;
$overview.css(posiLabel, -(slideIndex - self.moveNumber) * slideSize);
}

contentStyle[posiLabel] = -slideIndex * slideSize;

$overview.animate(
contentStyle
, {
queue : false
queue : false
, duration : self.options.animation ? self.options.animationTime : 0
, always : function()
{
, always : function() {
/**
* The move event will trigger when the carousel slides to a new slide.
*
* @event move
*/
$container.trigger("move", [$slides[self.slideCurrent], self.slideCurrent]);
}
});
});

setButtons();
_setButtons();
self.start();

return self;
};

function setButtons()
{
if(self.options.buttons && !self.options.infinite)
{
/**
* @method _setButtons
* @private
*/
function _setButtons() {
if(self.options.buttons && !self.options.infinite) {
$prev.toggleClass("disable", self.slideCurrent <= 0);
$next.toggleClass("disable", self.slideCurrent >= self.slidesTotal - slidesVisible);
}

if(self.options.bullets)
{
if(self.options.bullets) {
$bullets.removeClass("active");
$($bullets[self.slideCurrent]).addClass("active");
}
}

return initialize();
return _initialize();
}

$.fn[pluginName] = function(options)
{
return this.each(function()
{
if(!$.data(this, "plugin_" + pluginName))
{
/**
* @class tinycarousel
* @constructor
* @param {Object} options
@param {Number} [options.start=0] The slide to start with.
@param {String} [options.axis=x] Vertical or horizontal scroller? ( x || y ).
@param {Boolean} [options.buttons=true] Show previous and next navigation buttons.
@param {Boolean} [options.bullets=false] Is there a page number navigation present?
@param {Boolean} [options.interval=false] Move to another block on intervals.
@param {Number} [options.intervalTime=3000] Interval time in milliseconds.
@param {Boolean} [options.animate=true] False is instant, true is animate.
@param {Number} [options.animationTime=1000] How fast must the animation move in ms?
@param {Boolean} [options.infinite=true] Infinite carousel.
*/
$.fn[pluginName] = function(options) {
return this.each(function() {
if(!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin($(this), options));
}
});
};
}));
}));
Loading