var oCarousel = '';
$(function () {
var _settings = {
divContainer: "#carousel",
btPrevSlide: ".prevSlide",
btNextSlide: ".nextSlide",
direction: 0,
endReachedFunc: function () {
console.log('end reached')
}
};
oCarousel = new ContinuousCarouselV2(_settings, 1);
});
var ContinuousCarouselV2 = function (pSettings, pAutoRun) {
this.hInterval = 0;
this.numItems = 0;
this.ctItems = 0;
this.DIR = {
RtoL: 0,
LtoR: 1,
STOP: 2
};
this.iniDirection = 0;
this.iniStep = 0;
this.currDirection = 0;
this.$ulContainer = '';
this.currItemWidth = 0;
this.currPos = 0;
this.settings = {
// jQuery selectors
divContainer: '', // Required. jQuery Div ID. With overflow:hidden. e.g.: #carousel
ulContainer: '', // Optional
btPrevSlide: '',
btNextSlide: '',
//
endReachedFunc: '', // Function to invoke when all items are slid to one side
direction: 0, // 0: right to left | 1: left to right | 2: No automatic sliding
step: 1,
interval: 30,
fastStep: 3,
fastInterval: 5
};
this.options = {};
this.init = function (pSettings, pAutoRun) {
var _me = this,
_opts = _me.options = (pSettings) ? $.extend({}, _me.settings, pSettings) : $.extend({}, _me.settings);
if (!_opts.ulContainer) {
_opts.ulContainer = _opts.divContainer + " ul";
}
_me.currSpeed = _opts.speed;
_me.currDirection = _me.iniDirection = _opts.direction;
_me.iniStep = _opts.step;
_me.$ulContainer = $(_opts.ulContainer).css({
'width': 999999,
'position': 'relative'
});
_me.bindEvents();
if (_opts.endReachedFunc) {
_me.computeNumItems()
}
if (pAutoRun) {
_me.run()
}
};
this.bindEvents = function () {
var _me = this,
_opts = _me.options;
_me.$ulContainer.hover(function () {
_me.stopAnim()
}, function () {
_me.resumeAnim()
});
$(_opts.btNextSlide).hover(function (e) {
_me.setLoop(1, _me.DIR.RtoL)
}, function () {
_me.setLoop(0, _me.iniDirection)
});
$(_opts.btPrevSlide).hover(function (e) {
_me.setLoop(1, _me.DIR.LtoR)
}, function () {
_me.setLoop(0, _me.iniDirection)
});
};
this.run = function () {
var _me = this,
_LtoR = (_me.options.direction == _me.DIR.LtoR);
(_LtoR) ? _me.setLtoR() : _me.setRtoL();
_me.setLoop(0, _LtoR);
};
this.setLoop = function (pFast, pDirection) {
var _me = this,
_opts = _me.options,
_interval = (pFast) ? _opts.fastInterval : _opts.interval;
_opts.step = (pFast) ? _opts.fastStep : _me.iniStep;
if (_me.hInterval) { clearRequestInterval(_me.hInterval) }
//if (_me.hInterval) { clearInterval(_me.hInterval) }
_me.currDirection = pDirection;
_me.hInterval = requestInterval(function () { _me.loop() }, _interval);
//_me.hInterval = setInterval(function () {
// _me.loop()
//}, _interval);
};
this.stopAnim = function () {
this.currDirection = this.DIR.STOP;
};
this.resumeAnim = function () {
this.currDirection = this.iniDirection;
};
this.setRtoL = function () {
var _me = this,
_opts = _me.options;
_me.currItemWidth = $(_me.$ulContainer).children(':first').outerWidth(true);
_me.currPos = 0;
_me.$ulContainer.css('margin-left', 0);
};
this.setLtoR = function () {
var _me = this,
_opts = _me.options,
_$ul = _me.$ulContainer,
_$currItem = _$ul.children(':last');
_me.currItemWidth = _$currItem.outerWidth(true);
_me.currPos = -1 * _me.currItemWidth;
_$ul.css('margin-left', _me.currPos);
_$currItem.prependTo(_$ul);
};
this.loop = function () {
var _me = this,
_opts = _me.options,
_$ul = _me.$ulContainer,
_currItemWidthNeg;
if (_me.currDirection != _me.DIR.STOP) {
if (_me.currDirection == _me.DIR.RtoL) { // Right To Left
_me.currPos -= _opts.step;
_currItemWidthNeg = -1 * _me.currItemWidth;
if (_me.currPos < _currItemWidthNeg) {
_me.currPos = _currItemWidthNeg
}
_$ul.css('margin-left', _me.currPos);
if (_me.currPos == _currItemWidthNeg) {
_$ul.children(':first').appendTo(_$ul);
_me.setRtoL();
if (_opts.endReachedFunc) {
_me.ctrlCounter(_me.currDirection)
}
}
} else {
_me.currPos += _opts.step;
if (_me.currPos > 0) {
_me.currPos = 0;
}
_$ul.css('margin-left', _me.currPos);
if (_me.currPos == 0) {
_me.setLtoR();
if (_opts.endReachedFunc) {
_me.ctrlCounter(_me.currDirection)
}
}
}
}
};
this.computeNumItems = function (pNum) {
this.numItems = pNum || this.$ulContainer.children().length;
this.ctItems = 0;
};
this.ctrlCounter = function (pDirection) {
var _me = this,
_opts = _me.options;
_me.ctItems += (pDirection == _opts.direction) ? 1 : -1;
if (Math.abs(_me.ctItems) >= _me.numItems - 1) {
_me.ctItems = 0;
_opts.endReachedFunc();
}
};
//
this.init(pSettings, pAutoRun);
};
/*
* Drop in replace functions for setTimeout() & setInterval() that
* make use of requestAnimationFrame() for performance where available
* http://www.joelambert.co.uk
* Copyright 2011, Joe Lambert.
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
// requestAnimationFrame() shim by Paul Irish
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
/**
* Behaves the same as setInterval except uses requestAnimationFrame() where possible for better performance
* @param {function} fn The callback function
* @param {int} delay The delay in milliseconds
*/
window.requestInterval = function(fn, delay) {
if( !window.requestAnimationFrame &&
!window.webkitRequestAnimationFrame &&
!(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support
!window.oRequestAnimationFrame &&
!window.msRequestAnimationFrame)
return window.setInterval(fn, delay);
var start = new Date().getTime(),
handle = new Object();
function loop() {
handle.value = requestAnimFrame(loop);
var current = new Date().getTime(),
delta = current - start;
if(delta >= delay) {
fn.call();
start = new Date().getTime();
}
};
handle.value = requestAnimFrame(loop);
return handle;
}
/**
* Behaves the same as clearInterval except uses cancelRequestAnimationFrame() where possible for better performance
* @param {int|object} fn The callback function
*/
window.clearRequestInterval = function(handle) {
window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) :
window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) :
window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */
window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) :
window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) :
clearInterval(handle);
};
/**
* Behaves the same as setTimeout except uses requestAnimationFrame() where possible for better performance
* @param {function} fn The callback function
* @param {int} delay The delay in milliseconds
*/
window.requestTimeout = function(fn, delay) {
if( !window.requestAnimationFrame &&
!window.webkitRequestAnimationFrame &&
!(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support
!window.oRequestAnimationFrame &&
!window.msRequestAnimationFrame)
return window.setTimeout(fn, delay);
var start = new Date().getTime(),
handle = new Object();
function loop(){
var current = new Date().getTime(),
delta = current - start;
delta >= delay ? fn.call() : handle.value = requestAnimFrame(loop);
};
handle.value = requestAnimFrame(loop);
return handle;
};
/**
* Behaves the same as clearTimeout except uses cancelRequestAnimationFrame() where possible for better performance
* @param {int|object} fn The callback function
*/
window.clearRequestTimeout = function(handle) {
window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) :
window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) :
window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */
window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) :
window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) :
clearTimeout(handle);
};
<div id="container">
<div class="arrow"><a href="#" class="prevSlide">Prev</a>
</div>
<div id="carousel" style="float:left">
<ul>
<li style="width:130px">
<h3>1</h3>
</li>
<li style="width:340px">
<h3>2</h3>
</li>
<li style="width:260px">
<h3>3</h3>
</li>
<li style="width:200px">
<h3>4</h3>
</li>
<li style="width:380px">
<h3>5</h3>
</li>
</ul>
</div>
<div class="arrow"><a href="#" class="nextSlide">Next</a>
</div>
</div>
#container {
clear:both;
float:left;
width:940px;
}
#container .arrow {
float:left;
margin:10px;
line-height:230px;
font-size:large;
font-weight:bold;
}
#carousel {
width: 350px;
overflow:hidden;
height:252px;
border:1px solid black;
}
#carousel ul {
width: 999999px;
padding: 0;
margin: 0;
}
#carousel ul li {
width:239px;
text-align: center;
height: 250px;
list-style: none;
float: left;
line-height:228px;
border:1px solid red;
}