Implementing an H5 Lottery Turntable with CSS and JavaScript
This tutorial explains how to create a lottery wheel in HTML5 by designing the turntable layout using CSS transforms, controlling rotation with JavaScript, managing click locks, applying easing for a smooth slowdown, and adjusting prize probabilities through weighted random selection, complete with full source code examples.
In e‑commerce apps, lottery wheels like Pinduoduo's are common; this article shows how to build a similar effect using HTML5.
CSS Rotation Syntax
Review of transform and rotate() for setting rotation angles, and transform-origin for defining the rotation center.
<style>
.item0{...transform-origin: right bottom;transform: rotate(-0deg);}
.item1{...transform-origin: right bottom;transform: rotate(-60deg);}
</style>
<div id="box">
<div class="item0"></div>
<div class="item1"></div>
</div>Turntable Layout
Initial idea of rotating six rectangles around a common point fails due to overlapping; the correct approach splits the wheel into left and right halves, each using three rectangles with appropriate overflow:hidden and opposite rotation origins, then merges them.
<style>
.left .item{background-color: var(--clr);transform-origin: right bottom;transform: rotate(calc(60deg * var(--i)));}
.right .item{background-color: var(--clr);transform-origin: left bottom;transform: rotate(calc(60deg * var(--i)));}
</style>
<div id="box">
<div class="left">
<div class="item" style="--i:0;--clr:#ff7875;"></div>
...
</div>
<div class="right">
<div class="item" style="--i:0;--clr:#d3f261;"></div>
...
</div>
</div>Turntable Rotation
Rotate the outer container #box while keeping the central button stationary by applying an opposite rotation to the button.
box.style.transform = `rotate(${begin}deg)`;
btn.style.transform = `translate(-50%, -50%) rotate(${-begin}deg)`;The basic rotation script binds a click event to the button, selects a random index (0‑5), calculates the target angle, and animates the wheel with a fixed step.
const box = document.getElementById('box'), btn = document.getElementById('btn');
btn.addEventListener('click', () => {
const randomIndex = parseInt(Math.random() * 6);
run(randomIndex * 60 + 30);
});
let timer = null;
function run(angle) {
let begin = 0, base = 1800;
timer = setInterval(() => {
const finalAngle = base + angle;
if (begin >= finalAngle) clearInterval(timer);
box.style.transform = `rotate(${begin}deg)`;
btn.style.transform = `translate(-50%, -50%) rotate(${-begin}deg)`;
begin += 30;
}, 16);
}Improving Experience
Introduce a click lock ( clickLock ) to prevent re‑clicking during rotation and modify the animation to decelerate using a diminishing step calculated as step = (final - current) * ratio .
let clickLock = false;
btn.addEventListener('click', () => {
if (clickLock) return;
...
});
function run(angle) {
clickLock = true;
let current = 0, final = 1800, ratio = 0.5;
const timer = setInterval(() => {
if (current >= final) { clickLock = false; clearInterval(timer); }
const step = (final - current) * ratio;
current += Math.ceil(step);
box.style.transform = `rotate(${current}deg)`;
btn.style.transform = `translate(-50%, -50%) rotate(${-current}deg)`;
}, 16);
}Controlling Winning Probability
Use a weighted array to assign custom probabilities; the example gives a 1% chance to prizes 0‑4 and 95% to prize 5.
function getRandomIndex() {
const weights = [0,1,2,3,4,100];
const random = Math.floor(Math.random() * 100);
const newWeights = weights.concat(random).sort((a,b)=>a-b);
return newWeights.indexOf(random);
}Full Code and Summary
The article concludes that the turntable can be built by combining layout splitting, container rotation with easing, click locking, and weighted random selection to control prize distribution.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.