I’ve been working a few days on this spinner control, though I haven’t had very much luck getting it to work the way I need. It was originally code I found elsewhere, and repurposed for my own needs – so it’s just a little bit over my head.
HTML:
<ul class="picker">
<li class="pickerItem"><span class="value">1st Item Test</span></li>
<li class="pickerItem"><span class="value">2nd Item Test</span></li>
<li class="pickerItem"><span class="value">3rd Item Test</span></li>
<li class="pickerItem win"><span class="value">4th Item Test</span></li>
<li class="pickerItem"><span class="value">5th Item Test</span></li>
<li class="pickerItem"><span class="value">6th Item Test</span></li>
<li class="pickerItem"><span class="value">7th Item Test</span></li>
<li class="pickerItem"><span class="value">8th Item Test</span></li>
<li class="pickerItem"><span class="value">9th Item Test</span></li>
<li class="pickerItem"><span class="value">10th Item Test</span></li>
<li class="pickerItem last"><span class="value">11th Item Test</span></li>
</ul>
<div class="clear"></div>
<p><a href="#" id="start">start</a></p>
<p>Position: <span id="position">0</span></p>
<p>Speed: <span id="speed">0</span></p>
<p>Deceleration: <span id="deceleration">0</span></p>
Javascript:
var marqueeRunning = false;
var winElement;
var fullSpeed = 60;
var speed = fullSpeed;
var deceleration = 3;
var rotationTotal = 10;
var currentRotation = 0;
$(document).ready(function() {
winElement = $(".pickerItem.win");
$(".pickerItem").last().addClass("last");
$(".picker").each(function() {
var i = 0;
$(this).find(".pickerItem").each(function() {
var $this = $(this);
$this.css("top", i);
i += $this.height();
});
});
$('#start').click(function() {
if (!marqueeRunning) {
speed = fullSpeed;
$("#speed").html(speed);
//marqueeRunning = true;
var countScrolls = $('.picker .pickerItem').length;
marqueeRunning = true;
for (var i = 0; i < countScrolls; i++) {
doScroll($('.picker .pickerItem:nth-child(' + i + ')'));
}
setTimeout
(
function()
{
marqueeRunning = false;
},
1000
);
}
});
});
function slowDown()
{
var currentTop = Math.floor(winElement.css("top").replace("px",""));
/* -- Bounce Effect
if (currentTop != 0)
{
newSpeed = speed;
if (Math.abs(currentTop) < Math.abs(speed *4)) newSpeed = Math.floor(Math.abs(speed) - deceleration);
if (newSpeed === 0)
{
newSpeed = speed;
}
if (currentTop > 0)
{
speed = Math.floor(Math.abs(newSpeed));
}
else
{
speed = -Math.floor(Math.abs(newSpeed));
}
if (Math.abs(currentTop) < 3 && Math.abs(speed) === 3) speed = currentTop;
}
*/
$("#speed").html(speed);
if (currentTop === 0)
{
speed = 0;
$("#speed").html(speed + " (complete)");
}
}
function doScroll($ele) {
//alert($ele.css("top"));
var top = parseInt($ele.css("top"));
//console.log(' Outside - ' + top + ' < -' + 3*fullSpeed);
if (top < -(3 * fullSpeed)) { //bit arbitrary!
//console.log(' Inside - ' + top + ' < -' + 3*fullSpeed);
var $lastEle = $ele.closest('.picker').find(".last");
$lastEle.removeClass("last");
$ele.addClass("last");
var top = (parseInt($lastEle.css("top")) + $lastEle.height());
$ele.css("top", top);
}
$ele.animate({
top: (parseInt(top) - speed)
}, 100, 'linear', function() {
$("#position").html(winElement.css("top"));
if ($ele.get(0) === winElement.get(0) && marqueeRunning === false) setTimeout(slowDown, 10);
if (marqueeRunning || (Math.floor(winElement.css("top").replace("px","")) !== 0 && speed !== 0)) doScroll($(this))
});
}
You can view the current version here: http://jsfiddle.net/STLCajun/FYWtb/
What I’m trying to do is get the spinner to spin, and then after 5-6 rotations, slow down to the list item with the class “win” in the middle. Can someone point me in the right direction. Also, I’m not sure why, but it’s throwing a gap after the first set of items, and I’m not sure how t get rid of it.
Any help would be greatly appreciated.
I made simple example with scrollTo, to make the infinite loop I duplicated number of your items in scrolling window and at finishing scroll to last winning item:
HTML is almost the same as your,
CSS:
JS
The biggest problem with initial script is messing with global scope, and do easy things hard.