最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make a number wheel loop? - Stack Overflow

programmeradmin4浏览0评论

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
Add a ment  | 

3 Answers 3

Reset to default 4

I 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.

发布评论

评论列表(0)

  1. 暂无评论