I have a random number wheel from 0 to 9. The wheel spins down or up to land on the random number. How can I make it such that the wheel only spins down ? ( Once it reaches 9 the next number is 0, 1, 2... 9, 0, 1, 2) without having to have many divs.
function roll() {
var randomNum = Number((Math.random() * 100).toFixed(2));
var firstDigit = Number(Math.floor((randomNum) / 10 - 5));
var win = firstDigit;
if (win > 4) {
var rollm = win * 40 - 40 * 15;
document.getElementById("roll").style = "margin-top: " + rollm + "px ";
}
if (win < 4) {
var rollm = 180 - 40 * win - 380;
document.getElementById("roll").style = "margin-top: " + rollm + "px ";
}
if (win == 4) {
var rollm = 360;
document.getElementById("roll").style = "margin-top: -" + rollm + "px ";
}
}
body {
color: #fff;
}
#roll {
transition: .5s ease;
}
.ticker {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0px 15px 26px;
border-color: transparent #fff transparent;
margin: 0 -20px;
transform: translateY(-75px);
}
#roll {
width: 40px;
height: 360px;
background: #0077ee;
margin: 0 auto;
}
.roll-h {
width: 40px;
height: 120px;
margin: 0 auto;
overflow: hidden;
}
.shadow {
height: 40px;
margin: 0 auto;
transform: translateY(40px);
}
.black,
.his-h {
width: 40px;
height: 40px;
font-size: 20px;
line-height: 40px;
font-weight: 700;
text-align: center;
float: left;
}
.black {
background: black;
}
.floatleft {
float: left;
}
<div style="margin:0 auto; display:inline-block">
<div class="shadow"></div>
<div class="roll-h">
<div id="roll">
<div class="black">9</div>
<div class="black">0</div>
<div class="black">1</div>
<div class="black">2</div>
<div class="black">3</div>
<div class="black">4</div>
<div class="black">5</div>
<div class="black">6</div>
<div class="black">7</div>
<div class="black">8</div>
<div class="black">9</div>
<div class="black">0</div>
</div>
</div>
<div class="ticker"></div>
</div>
<button onClick="roll()" id="spin">Spin</button>
I have a random number wheel from 0 to 9. The wheel spins down or up to land on the random number. How can I make it such that the wheel only spins down ? ( Once it reaches 9 the next number is 0, 1, 2... 9, 0, 1, 2) without having to have many divs.
function roll() {
var randomNum = Number((Math.random() * 100).toFixed(2));
var firstDigit = Number(Math.floor((randomNum) / 10 - 5));
var win = firstDigit;
if (win > 4) {
var rollm = win * 40 - 40 * 15;
document.getElementById("roll").style = "margin-top: " + rollm + "px ";
}
if (win < 4) {
var rollm = 180 - 40 * win - 380;
document.getElementById("roll").style = "margin-top: " + rollm + "px ";
}
if (win == 4) {
var rollm = 360;
document.getElementById("roll").style = "margin-top: -" + rollm + "px ";
}
}
body {
color: #fff;
}
#roll {
transition: .5s ease;
}
.ticker {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0px 15px 26px;
border-color: transparent #fff transparent;
margin: 0 -20px;
transform: translateY(-75px);
}
#roll {
width: 40px;
height: 360px;
background: #0077ee;
margin: 0 auto;
}
.roll-h {
width: 40px;
height: 120px;
margin: 0 auto;
overflow: hidden;
}
.shadow {
height: 40px;
margin: 0 auto;
transform: translateY(40px);
}
.black,
.his-h {
width: 40px;
height: 40px;
font-size: 20px;
line-height: 40px;
font-weight: 700;
text-align: center;
float: left;
}
.black {
background: black;
}
.floatleft {
float: left;
}
<div style="margin:0 auto; display:inline-block">
<div class="shadow"></div>
<div class="roll-h">
<div id="roll">
<div class="black">9</div>
<div class="black">0</div>
<div class="black">1</div>
<div class="black">2</div>
<div class="black">3</div>
<div class="black">4</div>
<div class="black">5</div>
<div class="black">6</div>
<div class="black">7</div>
<div class="black">8</div>
<div class="black">9</div>
<div class="black">0</div>
</div>
</div>
<div class="ticker"></div>
</div>
<button onClick="roll()" id="spin">Spin</button>
Share
edited Jan 15, 2017 at 7:15
castletheperson
33.5k11 gold badges74 silver badges107 bronze badges
asked Jan 15, 2017 at 7:03
user7184660user7184660
3 Answers
Reset to default 4I modified your snippet a little bit to achieve the behavior you're asking for.
There are two problems though. First, you will need almost twice as many divs to animate the thing properly. Second, the transitionend
event is not supported in all browsers, and sometimes it needs to be prefixed, so if you care about supporting things like IE < 10, then it will not work for you out of the box.
Edit
As sugested in the other answer instead of using transitionend
event you may consider reseting the "wheel" position only when the button is clicked. This is fine but it will require a little more sophisticated implementation because you will need to remember (somehow) which position you need to reset to.
function roll() {
var win = Math.floor(Math.random() * 10);
var roll = document.getElementById("roll");
var onTransitionend = function () {
roll.classList.remove("animated");
roll.style = "margin-top: " + (- win * 40) + "px ";
roll.removeEventListener("transitionend", onTransitionend);
};
roll.classList.add("animated");
roll.style = "margin-top: " + (- win * 40 - 400) + "px ";
roll.addEventListener("transitionend", onTransitionend);
}
body {
color: #fff;
}
#roll.animated {
transition: .5s ease;
}
.ticker {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0px 15px 26px;
border-color: transparent #fff transparent;
margin: 0 -20px;
transform: translateY(-75px);
}
#roll {
width: 40px;
// height: 360px;
background: #0077ee;
margin: 0 auto;
}
.roll-h {
width: 40px;
height: 120px;
margin: 0 auto;
overflow: hidden;
}
.shadow {
height: 40px;
margin: 0 auto;
transform: translateY(40px);
}
.black,
.his-h {
width: 40px;
height: 40px;
font-size: 20px;
line-height: 40px;
font-weight: 700;
text-align: center;
float: left;
}
.black {
background: black;
}
.floatleft {
float: left;
}
<div style="margin:0 auto; display:inline-block">
<div class="shadow"></div>
<div class="roll-h">
<div id="roll">
<div class="black">9</div>
<div class="black">0</div>
<div class="black">1</div>
<div class="black">2</div>
<div class="black">3</div>
<div class="black">4</div>
<div class="black">5</div>
<div class="black">6</div>
<div class="black">7</div>
<div class="black">8</div>
<div class="black">9</div>
<div class="black">0</div>
<div class="black">1</div>
<div class="black">2</div>
<div class="black">3</div>
<div class="black">4</div>
<div class="black">5</div>
<div class="black">6</div>
<div class="black">7</div>
<div class="black">8</div>
<div class="black">9</div>
<div class="black">0</div>
</div>
</div>
<div class="ticker"></div>
</div>
<button onClick="roll()" id="spin">Spin</button>
One solution you could do is shift all of the divs to the top each time the button is pressed, so that it always needs to scroll down to get the the next number. Here is a more modular way of doing it:
document.getElementById('spin').onclick = makeSpinner('roll', function(num) {
// handle new number here
console.log(num);
});
function makeSpinner(id, callback) {
/* Initialization */
var rollDiv = document.getElementById(id);
var currentNum = 0;
for (var i = 0; i < 23; i++) {
rollDiv.appendChild(document.createElement('div'));
}
resetSpinner(9);
/* Helper Functions */
function getRandomInt(min, max) {
// min inclusive, max inclusive
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function resetSpinner(startNum) {
rollDiv.classList.remove('animatedSpinner');
rollDiv.style.marginTop = "0px";
rollDiv.scrollTop = 0;
rollDiv.classList.add('animatedSpinner');
for (var node = rollDiv.firstElementChild, num = startNum;
node !== null;
node = node.nextElementSibling, num = (num + 1) % 10) {
node.innerText = num;
}
}
/* Main Function */
return function () {
var previous = (currentNum + 9) % 10;
var distanceRolled = getRandomInt(1, 10) + 10;
currentNum = (currentNum + distanceRolled) % 10;
resetSpinner(previous);
rollDiv.style.marginTop = -40 * distanceRolled + "px";
typeof callback === 'function' && callback(currentNum);
};
}
#roll {
color: #fff;
width: 40px;
height: 360px;
background: #0077ee;
margin: 0 auto;
}
.animatedSpinner {
transition: 1s ease;
}
#roll > div {
background: black;
width: 40px;
height: 40px;
font-size: 20px;
line-height: 40px;
font-weight: 700;
text-align: center;
float: left;
}
.ticker {
width: 0;
height: 0;
border-style: solid;
border-width: 15px 0px 15px 26px;
border-color: transparent #fff transparent;
margin: 0 -20px;
transform: translateY(-75px);
}
.roll-h {
width: 40px;
height: 120px;
margin: 0 auto;
overflow: hidden;
}
.as-console-wrapper {
max-height: 60px !important;
}
<div style="margin:0 auto; display:inline-block">
<div class="roll-h">
<div id="roll"></div>
</div>
<div class="ticker"></div>
</div>
<button id="spin">Spin</button>
var p = document.getElementById("cont");
var max = 9; //max element in meter
//create items
for (var i = 0; i <= max; i++)
{
var child = document.createElement("div");
child.innerHTML = i;
child.style.top = (i * 30) + "px";
child.setAttribute('id', i);
p.appendChild(child);
}
//add listeners to buttons
document.getElementById('start').addEventListener('click', spin);
document.getElementById('stop').addEventListener('click', stopSpin);
//set up interval id so that in future timer can be stopped
var intervalId=null,randomNum=null;
//spin function
function spin()
{
randomNum=null;
intervalId=setInterval(function()
{
var temp = 0;
//decrease top value of each item by 5px; can by any number to make fast or slow
for (var i = 0; i <= max; i++)
{
var item = document.getElementById("" + i); //get item by its id 0-max
var itemTop = (parseInt(item.style.top)); //get item top in integer
item.style.top = (itemTop - 5) + "px"; //update top value
itemTop = (parseInt(item.style.top));//get updated value
if (itemTop < -30) //place element at last if below -30px
{
item.style.top = ((max - temp) * 30) + "px";
temp++;
}
//check if stopped button was pressed
if(itemTop==60&&randomNum==parseInt(item.innerHTML)) // pointer shows number at 60px
{
//stop meter
clearInterval(intervalId);
}
}
}, 20);
}
function stopSpin()
{
//just generate randome number at which meter should stop
randomNum=Math.floor((Math.random()*10)+0);
console.log(randomNum)
}
#pointer {
border: 5px solid black;
width: 35px;
height: 35px;
position: absolute;
left: 194px;
top: 63px;
opacity: 0.5;
}
#cont {
overflow: hidden;
border: 1px solid gray;
width: 30px;
height: 150px;
z-index: 1;
position: absolute;
left: 200px;
}
#cont>div {
backgroud: black;
border: 1px solid gray;
float: left;
text-align: center;
position: absolute;
width: 30px;
height: 30px;
z-index: 0;
}
<div id="cont">
</div>
<div id="pointer">
</div>
<button id='start'>start</button>
<button id='stop'>stop</button>
Checkout this JsFiddle
Main point is to place the previous element to the last
Little bit late but i hope this will help you.