Carousel - Cyclic Rotation
by abhitalks
HTML
<div class="controls">
<label>Speed <input id="speed" type="number" min="1" max="8" value="2" />x</label>
|
<label>Iterations <input id="iter" type="number" min="0" max="8" value="2" /></label>
</div>
<div class="cardList">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
CSS
* { box-sizing: border-box; padding: 0; margin: 0; }
.cardList {
position: relative; height: 100px; width: 300px;
margin: 10px; border: 2px solid #33e;
overflow: hidden; white-space: nowrap;
}
.card {
position: absolute; left: 0; top: 0; text-align: center;
height: 100px; width: 100px; line-height: 100px;
background-color: #99e;
font-family: monospace; font-size: 2em; color: #444;
border-left: 1px solid #33e; border-right: 1px solid #33e;
}
div.controls, button {
margin: 10px; padding: 8px; font-family: monospace;
}
div.controls input {
width: 48px; padding: 2px; text-align: center;
font-family: monospace;
}
JavaScript
var list = document.querySelector('.cardList'),
cards = document.querySelectorAll('.card'),
start = document.getElementById('start'),
stop = document.getElementById('stop'),
reset = document.getElementById('reset'),
raf, init = 0, counter = 0, lastCard, currentIteration = 0,
settings = {
'width': 100, 'height': 100, 'speed': 2,
'iterations': 2, 'count': cards.length
}
;
start.addEventListener('click', startClick);
stop.addEventListener('click', stopClick);
reset.addEventListener('click', resetClick);
initialize();
function initialize() {
[].forEach.call(cards, function(elem, idx) {
elem.style.left = (settings.width * idx) + 'px';
});
init = -(settings.width);
lastCard = cards[settings.count - 1];
counter = 0; currentIteration = 0;
settings.speed = +(document.getElementById('speed').value);
settings.iterations = +(document.getElementById('iter').value);
}
function startClick() {
initialize(); raf = window.requestAnimationFrame(keyframes);
}
function stopClick() { window.cancelAnimationFrame(raf); }
function resetClick() {
window.cancelAnimationFrame(raf);
document.getElementById('speed').value = '2';
document.getElementById('iter').value = '2';
initialize();
}
function keyframes() {
var currentCard, currentLeft = 0, newLeft = 0;
[].forEach.call(cards, function(elem, idx) {
elem.style.left = (parseInt(elem.style.left) - settings.speed) + 'px';
});
currentCard = cards[counter];
currentLeft = parseInt(currentCard.style.left);
if (currentLeft <= init) {
newLeft = parseInt(lastCard.style.left) + settings.width;
list.appendChild(currentCard);
currentCard.style.left = newLeft + 'px';
lastCard = currentCard;
counter = (counter + 1) % settings.count;
if ((settings.iterations > 0) && (counter >= (settings.count - 1))) {
currentIteration++;
}
}
if...