On Friday Blake and I were asked how to take a list of people and in a fun way choose a random winner.
For fun, here's the finalized pen.
See the Pen The Selectinator 3000 by Josh Fabean (@fabean) on CodePen.
There you can see all the code but I'll break some of the cooler parts for you. Worth noting I wrote all the code in ES6 and used Traceur on CodePen to compile it to ES5 and work for people.
Below is a nice helper function I created the other day trying to make something useful but under 140bytes of data. It takes an element query array and turns it into an actual usable array. Not sure if you've ran into that issue before but you cannot simply say document.getElementsByClass('my-class')
then loop through them, it needs to be made into an actual array for it to be usable.
// helper functions
function makeArray(r){return[].slice.call(r,0)};
To get the lightup effect I probably could have made a sass mixin based on class but doing it with javascript seemed cooler. So I grab everything with a class of light
, use math to grab a random one, then each 300 milliseconds run the function lightUp. Then we're simply just toggling a class and the CSS animation is doing the rest.
let lights = makeArray(document.getElementsByClassName('light'));
/* figure out what block we're going to light up next */
(function nextLight() {
let index = [Math.floor(Math.random() * lights.length)]; // math to grab a random element
let light = lights[index];
lightUp(light);
setTimeout(nextLight,300);
})();
// take the el passed in an toggle a class
function lightUp(light) {
light.classList.add('on');
setTimeout(function(){
light.classList.remove('on');
},1000);
}
Finally is my favorite, the function where you pass it in a string and it types it out slowly to get the cool typing effect. All I'm doing for that is you pass in the string, and time in milliseconds between each letter and it appends it to the end of the element we're typing in.
// get passed in a string, delay, and current iterator
// based on that output text to the screen
// in future we should pass in element we are rendering to, that would make this more reusable
// also you can remove the first if, that's pretty specific to this situation
function typeText(text, time, i = 0) {
if (terminal.style.bottom === '') {
// if bottom isn't defined see if we need to start the scrolling effect
screenScroll();
}
setTimeout(function(){
// on first iteration of the string I'm making a new line
// else we add to the line
if (i === 0 && terminal.innerHTML != '' && text != ' you lose') {
terminal.innerHTML += `<br /> ${text.charAt(i)}`;
} else {
terminal.innerHTML += text.charAt(i);
}
i++;
if (text.length >= i) {
typeText(text, time, i);
}
}, time);
}
This was my favorite pen I've made so far I really hope you enjoyed it.