Created
June 25, 2013 13:26
-
-
Save andrewburgess/5858417 to your computer and use it in GitHub Desktop.
jQuery plugin for creating a carousel that responds to touch events to swipe through the carousel.
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
(function ($) { | |
"use strict"; | |
var hasTouch = 'ontouchstart' in window; | |
//CONSTANTS | |
var MOVE_EVENT = hasTouch ? 'touchmove' : 'mousemove', | |
START_EVENT = hasTouch ? 'touchstart' : 'mousedown', | |
STOP_EVENT = hasTouch ? 'touchend' : 'mouseup'; | |
var methods = { | |
init: function (options) { | |
return this.each(function () { | |
var self = $(this), | |
data = self.data('carousel'); | |
if (!data) { | |
var settings = $.extend({ | |
index: 0, | |
snapDuration: 100, | |
threshold: 0, | |
imageWidth: 290, | |
autochange: true, | |
rotateDuration: 5000, | |
rotateExtraTime: 1000 | |
}, options); | |
self.css('left', settings.index * settings.imageWidth * -1); | |
data = { | |
options: settings, | |
position: { x: settings.index * settings.imageWidth * -1, y: 0 }, | |
offset: { x: 0, y: 0 }, | |
change: { x: 0, y: 0 }, | |
total: self.find('li').length, | |
moving: false, | |
lastChange: 0 | |
}; | |
self.data('carousel', data); | |
} | |
self.css('width', settings.imageWidth * (data.total + 1)); | |
self.bind(MOVE_EVENT, methods._move); | |
self.bind(START_EVENT, methods._start); | |
self.bind(STOP_EVENT, methods._stop); | |
if (!hasTouch) | |
self.bind('mouseout', methods._stop); | |
self.mobileCarousel('_resetTimer'); | |
}); | |
}, | |
_autorotate: function () { | |
var self = $(this); | |
var data = self.data('carousel'); | |
var now = Date.now(); | |
if (now - data.lastChange >= data.options.rotateDuration) { | |
data.options.index = (data.options.index + 1) % data.total; | |
self.mobileCarousel('change', data.options.index, data.options.rotateExtraTime); | |
data.lastChange = now; | |
self.mobileCarousel('_resetTimer'); | |
} | |
self.data('carousel', data); | |
}, | |
_move: function (ev) { | |
ev.preventDefault(); | |
var self = $(ev.currentTarget); | |
var data = self.data('carousel'); | |
if (!data.moving) | |
return; | |
var currentLeft = parseInt(self.css('left'), 10); | |
var pageX = 0; | |
if (hasTouch) | |
pageX = ev.originalEvent.touches[0].pageX; | |
else | |
pageX = ev.pageX; | |
var diff = pageX - data.offset.x; | |
self.css('left', currentLeft + diff); | |
data.change.x += diff; | |
data.offset.x = pageX; | |
data.lastChange = Date.now(); | |
}, | |
_start: function (ev) { | |
ev.preventDefault(); | |
var self = $(ev.currentTarget); | |
var data = self.data('carousel'); | |
var pageX = 0; | |
if (hasTouch) | |
pageX = ev.originalEvent.touches[0].pageX; | |
else | |
pageX = ev.pageX; | |
data.moving = true; | |
data.offset.x = pageX; | |
}, | |
_stop: function (ev) { | |
ev.preventDefault(); | |
var self = $(ev.currentTarget); | |
var data = self.data('carousel'); | |
if (data.moving === false) { | |
data.change.x = 0; | |
data.change.y = 0; | |
return; | |
} | |
data.moving = false; | |
if (Math.abs(data.change.x) >= data.options.threshold) { | |
if (data.change.x > 0) { | |
data.options.index = Math.max(data.options.index - 1, 0); | |
} else if (data.change.x < 0) { | |
data.options.index = Math.min(data.options.index + 1, data.total - 1); | |
} | |
} | |
self.mobileCarousel('change', data.options.index); | |
data.change.x = 0; | |
data.change.y = 0; | |
}, | |
_resetTimer: function () { | |
var self = $(this); | |
var data = self.data('carousel'); | |
if (data.options.autochange) { | |
data.lastChange = Date.now(); | |
self.delay(data.options.rotateDuration, 'carousel').queue('carousel', function () { | |
self.mobileCarousel('_autorotate'); | |
}).dequeue('carousel'); | |
} | |
}, | |
change: function (index, extraTime) { | |
if (extraTime === undefined) | |
extraTime = 0; | |
var self = $(this); | |
var data = self.data('carousel'); | |
self.animate({ left: (-1 * data.options.imageWidth * index) }, data.options.snapDuration + extraTime, function () { | |
self.mobileCarousel('_resetTimer'); | |
}); | |
data.options.index = index; | |
} | |
}; | |
$.fn.mobileCarousel = function (method) { | |
if (methods[method]) { | |
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); | |
} else if (typeof method === 'object' || !method) { | |
return methods.init.apply(this, arguments); | |
} else { | |
$.error('Method ' + method + ' does not exist on jQuery.mobileCarousel'); | |
} | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment