1

I have a list of names which are constantly looped through and rendered to the h1 tag #randomName. When the #pickName button is pressed a random name is selected from the names list (and then removed).

For the purpose of what I'm trying to do this is great, but what I'd love to be able to do is when the #pickName link is clicked, have the list of names that are looping on screen to slowly slow down (say 3 seconds) and then settle on one of the names (and use this in the alert).

const names = Array('Craig O Mahony', 'Nick Farmer', 'Stuart Lister', 'Lee Rogers', 'Mick O Connor', 'Paul Alexander', 'Robin Allison', 'Neil Bellion', 'Tom / Tim / Mitch', 'Steve Casey', 'Ian Condley', 'Ken Dovey', 'Tony Doyle', 'Dave Field', 'James Field', 'Steve Fuller', 'Jim Harrison', 'Ray Harrison', 'Mick Hennessey', 'John Hodges', 'Shaun Hooper', 'Phil Large', 'Steve Lowe', 'Nevin McDermott', 'Tony McDonnell', 'Steve Nye', 'Paul Read', 'Wayne Rogers', 'Pete Sears', 'Pete Smith', 'Dave Wrafter', 'Rob Wyatt', );

const h1$ = $('#randomName');
var currentMatch = "match";
var counter = 1;
let idx = 0;

setInterval(() => {
  h1$.text(names[idx++ % names.length]);
}, 100);

$("#pickName").on('click', function() {
  const name = names[Math.floor(Math.random() * names.length)];

  alert(name);

  names.splice($.inArray(name, names), 1);
  //$('#' + name).remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="btn btn-default btn-lg" id="pickName">Draw Player</a>

<h1 style="font-size:4em;padding-top:15px" id="randomName"></h1>

https://jsfiddle.net/nf1eL56x/

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
SxChoc
  • 619
  • 3
  • 10
  • 26
  • 1
    The slowdown is a bit more work, but in terms of getting it to pick the player which is currently on screen, can't you just get the current `text` value of the `#randomName` header and select/remove that one, rather than doing it randomly? – Robin Zigmond Feb 06 '19 at 16:35
  • I probably could yes, it's the slowing part that I'm really after. This is for a cup draw which will be shown on a big screen and I'm trying to create a bit of suspense! – SxChoc Feb 06 '19 at 16:41

3 Answers3

2

You can adjust this effect by changing slow = 100 and time < 1000 to what ever you like, you can even manipulate slow inside display

const names = Array('Craig O Mahony', 'Nick Farmer', 'Stuart Lister', 'Lee Rogers', 'Mick O Connor', 'Paul Alexander', 'Robin Allison', 'Neil Bellion', 'Tom / Tim / Mitch', 'Steve Casey', 'Ian Condley', 'Ken Dovey', 'Tony Doyle', 'Dave Field', 'James Field', 'Steve Fuller', 'Jim Harrison', 'Ray Harrison', 'Mick Hennessey', 'John Hodges', 'Shaun Hooper', 'Phil Large', 'Steve Lowe', 'Nevin McDermott', 'Tony McDonnell', 'Steve Nye', 'Paul Read', 'Wayne Rogers', 'Pete Sears', 'Pete Smith', 'Dave Wrafter', 'Rob Wyatt', );

const h1$ = $('#randomName');
var currentMatch = "match";
var counter = 1;
var time = 100;
let idx = 0;
var slow = 0;


$("#pickName").on('click', function() {
  slow = 25;
});

function display() {
  if(time < 500) {
    h1$.text(names[idx++ % names.length]);
    slow *= 2;
    time += slow;
    setTimeout(display, time);
  } else {
     const name = h1$.text();

    alert(name);
  }
}

display();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="btn btn-default btn-lg" id="pickName">Draw Player</a>

<h1 style="font-size:4em;padding-top:15px" id="randomName"></h1>
ponury-kostek
  • 7,824
  • 4
  • 23
  • 31
0

To achieve this you could clear the interval when the button is clicked then recursively create a new timeout which extends in length for up to 3 seconds before finally picking the name which is displayed in the h1 at the end of that period, something like this:

const names = Array('Craig O Mahony', 'Nick Farmer', 'Stuart Lister', 'Lee Rogers', 'Mick O Connor', 'Paul Alexander', 'Robin Allison', 'Neil Bellion', 'Tom / Tim / Mitch', 'Steve Casey', 'Ian Condley', 'Ken Dovey', 'Tony Doyle', 'Dave Field', 'James Field', 'Steve Fuller', 'Jim Harrison', 'Ray Harrison', 'Mick Hennessey', 'John Hodges', 'Shaun Hooper', 'Phil Large', 'Steve Lowe', 'Nevin McDermott', 'Tony McDonnell', 'Steve Nye', 'Paul Read', 'Wayne Rogers', 'Pete Sears', 'Pete Smith', 'Dave Wrafter', 'Rob Wyatt', );

const $h1 = $('#randomName');
let idx = 0;
let backoffMs = 75;

var interval = setInterval(() => {
  $h1.text(names[idx++ % names.length]);
}, 100);

$("#pickName").on('click', function() {
  $(this).off();
  clearInterval(interval);
  reduceInterval(new Date(), 100);
});

function reduceInterval(start, delay) {
  setTimeout(() => {
    $h1.text(names[idx++ % names.length]);
    var dif = start.getTime() - new Date().getTime();
    var secs = Math.abs(dif / 1000);
    if (secs < 3) {
      reduceInterval(start, delay + backoffMs);
    } else {
      getName();
    }
  }, delay + backoffMs);
}

function getName() {
  console.log($h1.text());
}
h1 {
  font-size: 4em;
  padding-top: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="btn btn-default btn-lg" id="pickName">Draw Player</a>

<h1 id="randomName"></h1>

I would also suggest randomising the array index you display as right now it's obvious the same names come through in order.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

Here is a general solution that defines a setDeceleratingInterval using setTimeout and setInterval:

const names = ['Craig O Mahony','Nick Farmer','Stuart Lister','Lee Rogers','Mick O Connor','Paul Alexander','Robin Allison','Neil Bellion','Tom / Tim / Mitch','Steve Casey','Ian Condley','Ken Dovey','Tony Doyle','Dave Field','James Field','Steve Fuller','Jim Harrison','Ray Harrison','Mick Hennessey','John Hodges','Shaun Hooper','Phil Large','Steve Lowe','Nevin McDermott','Tony McDonnell','Steve Nye','Paul Read','Wayne Rogers','Pete Sears','Pete Smith','Dave Wrafter','Rob Wyatt'];

const h1$ = $('#randomName');
let idx = 0;

const randomizeH1 = () => h1$.text(names[++idx % names.length]);

let timer = setInterval(randomizeH1, 100);

const showName = () => {
  const name = names[idx % names.length];
  alert(name);
  names.splice(idx, 1);
  timer = setInterval(randomizeH1, 100);
};

function setDeceleratingInterval(cb, cb2, dtInit, factor, total) {
  let remaining = total;
  let dt = dtInit;

  const internalTimer = () => {
    remaining -= dt;
    dt *= factor;
    if (remaining >= 0) {
      setTimeout(internalTimer, dt);
      cb();
    } else {
      cb2();
    }
  };
  internalTimer();
}

$("#pickName").on('click', () => {
  clearInterval(timer);
  setDeceleratingInterval(randomizeH1, showName, 100, 1.1, 3000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<h1 id="randomName"></h1>

<a class="btn btn-default btn-lg" id="pickName">Draw Player</a>
jo_va
  • 13,504
  • 3
  • 23
  • 47