Building a Fun Lottery Program with HTML, CSS, and JavaScript
This article walks through creating an engaging, fair lottery program for an annual event using plain JavaScript, including random shuffling, localStorage persistence, and a horse‑race animation built with HTML and CSS, complete with reusable functions and step‑by‑step code explanations.
The article explains how to write a proper lottery program for a yearly gathering, emphasizing fairness, repeatability, and visual appeal.
It starts with three utility functions: function random(m, n) { return m + Math.floor(Math.random() * n); } , function randomItem(arr, from = 0, to = arr.length) { const index = random(from, to); return { index, value: arr[index] }; } , and function shuffle(arr) { for (let i = arr.length; i > 0; i--) { const { index } = randomItem(arr, 0, i); [arr[index], arr[i - 1]] = [arr[i - 1], arr[index]]; } return arr; } .
To keep track of winners across page reloads, the code uses localStorage with a key prize10 . Functions getResults() and addResults(players) read and write a comma‑separated list of winners, while filterWinner(members) removes already‑won participants.
The UI consists of two buttons – “Start” and “Clear”. The start button shuffles the participant list, selects the last six people, records the top three as winners, trims the list, and then calls await race(candidates) . The clear button removes the stored results from localStorage .
A minimal HTML skeleton is required: a <!DOCTYPE html> document with a <div id="control"> containing the buttons, and a <div id="track"> where the animated horses will be inserted.
Simple CSS styles set the page layout, style the control panel, and define the appearance of the horse and player elements, including positioning and sizing.
The core race logic builds an array durations where each entry is a base time increased by a random 0.02–0.05 s. The partRace(durations, factor) function splits each total duration into sub‑durations with a small ±0.1 factor perturbation, returning an array of stage times.
The race(candidates) function creates four race stages (round1‑round4) using partRace , maps each candidate to a visual horse element, and then animates each horse through the stages by chaining promises that call raceHorse . The final stage adds medal emojis (🥇🥈🥉) to the winners.
The animation helper raceHorse(horseEl, duration, from = 30, by = trackLen / 4) returns a Promise that updates horseEl.style.left on each requestAnimationFrame until the elapsed time reaches the given duration.
All functions are combined at the end of the script, producing a complete, interactive lottery page where clicking “Start” runs the race animation and records winners, and “Clear” resets the state. The final effect shows a horse‑race style animation with the top three participants receiving medals.
For further reference, the article provides GitHub links to the 2017 version and the full repository.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.