In this tutorial, we will create a simple Spin Wheel App using HTML, CSS, JavaScript, and the Chart.js library. Users can spin the wheel to get a random value between 1 to 6, and the result will be displayed dynamically on the wheel.

HTML Structure
We have a container with a canvas for the wheel, a button to spin the wheel, and an image of an arrow to indicate the spinning direction.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Spin Wheel App</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<div class="container">
<canvas id="wheel"></canvas>
<button id="spin-btn">Spin</button>
<img src="spinner-arrow-.svg" alt="spinner-arrow" />
</div>
<div id="final-value">
<p>Click On The Spin Button To Start</p>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.1.0/chartjs-plugin-datalabels.min.js"></script>
<script src="script.js"></script>
</body>
</html>HTMLExplanation:
<canvas id="wheel"></canvas>: This canvas will be used to draw the spinning wheel.<button id="spin-btn">Spin</button>: A button to trigger the spinning action.<img src="spinner-arrow-.svg" alt="spinner-arrow" />: An image to indicate the direction of spinning.
CSS Styling
Let’s add some CSS to style our Spin Wheel App.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
height: 100vh;
background: linear-gradient(135deg, #c3a3f1, #6414e9);
}
.wrapper {
width: 90%;
max-width: 34.37em;
max-height: 90vh;
background-color: #ffffff;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
padding: 3em;
border-radius: 1em;
box-shadow: 0 4em 5em rgba(27, 8, 53, 0.2);
}
.container {
position: relative;
width: 100%;
height: 100%;
}
#wheel {
max-height: inherit;
width: inherit;
top: 0;
padding: 0;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
#spin-btn {
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
height: 26%;
width: 26%;
border-radius: 50%;
cursor: pointer;
border: 0;
background: radial-gradient(#fdcf3b 50%, #d88a40 85%);
color: #c66e16;
text-transform: uppercase;
font-size: 1.8em;
letter-spacing: 0.1em;
font-weight: 600;
}
img {
position: absolute;
width: 4em;
top: 45%;
right: -8%;
}
#final-value {
font-size: 1.5em;
text-align: center;
margin-top: 1.5em;
color: #202020;
font-weight: 500;
}
@media screen and (max-width: 768px) {
.wrapper {
font-size: 12px;
}
img {
right: -5%;
}
}CSSExplanation:
*: Sets some basic styles for all elements like padding, margin, and box-sizing..wrapper: Styles the main container that houses the wheel and button.#wheeland#spin-btn: Styles for the wheel canvas and spin button respectively.
JavaScript Logic
Finally, we’ll write the JavaScript code to create the spinning wheel functionality using Chart.js and JavaScript.
const wheel = document.getElementById("wheel");
const spinBtn = document.getElementById("spin-btn");
const finalValue = document.getElementById("final-value");
const rotationValues = [
{ minDegree: 0, maxDegree: 30, value: 2 },
{ minDegree: 31, maxDegree: 90, value: 1 },
{ minDegree: 91, maxDegree: 150, value: 6 },
{ minDegree: 151, maxDegree: 210, value: 5 },
{ minDegree: 211, maxDegree: 270, value: 4 },
{ minDegree: 271, maxDegree: 330, value: 3 },
{ minDegree: 331, maxDegree: 360, value: 2 },
];
const data = [16, 16, 16, 16, 16, 16];
const pieColors = ["#8b35bc", "#b163da", "#8b35bc", "#b163da", "#8b35bc", "#b163da"];
let myChart = new Chart(wheel, {
plugins: [ChartDataLabels],
type: "pie",
data: {
labels: [1, 2, 3, 4, 5, 6],
datasets: [
{
backgroundColor: pieColors,
data: data,
},
],
},
options: {
responsive: true,
animation: { duration: 0 },
plugins: {
tooltip: false,
legend: {
display: false,
},
datalabels: {
color: "#ffffff",
formatter: (_, context) => context.chart.data.labels[context.dataIndex],
font: { size: 24 },
},
},
},
});
const valueGenerator = (angleValue) => {
for (let i of rotationValues) {
if (angleValue >= i.minDegree && angleValue <= i.maxDegree) {
finalValue.innerHTML = `<p>Value: ${i.value}</p>`;
spinBtn.disabled = false;
break;
}
}
};
let count = 0;
let resultValue = 101;
spinBtn.addEventListener("click", () => {
spinBtn.disabled = true;
finalValue.innerHTML = `<p>Good Luck!</p>`;
let randomDegree = Math.floor(Math.random() * (355 - 0 + 1) + 0);
let rotationInterval = window.setInterval(() => {
myChart.options.rotation = myChart.options.rotation + resultValue;
myChart.update();
if (myChart.options.rotation >= 360) {
count += 1;
resultValue -= 5;
myChart.options.rotation = 0;
} else if (count > 15 && myChart.options.rotation == randomDegree) {
valueGenerator(randomDegree);
clearInterval(rotationInterval);
count = 0;
resultValue = 101;
}
}, 10);
});JavaScriptExplanation:
rotationValues: An array that defines the value range for each segment of the wheel.dataandpieColors: Data and colors for the pie chart segments.myChart: Initializes a new Chart.js pie chart with the wheel canvas.valueGenerator: A function that generates a value based on the angle of rotation.spinBtn.addEventListener("click", () => { ... }): Event listener for the spin button click event. It triggers the wheel spinning animation and calculates the final value based on the rotation angle.
Conclusion
That’s it! You’ve successfully created a Spin Wheel App using HTML, CSS, JavaScript, and Chart.js. Users can now spin the wheel to get a random value between 1 to 6, and the result will be displayed dynamically on the wheel. Feel free to customize and extend this project further to suit your needs!
Happy Coding!

Indian States Spin Wheel
body {
text-align: center;
font-family: Arial, sans-serif;
}
#wheel {
width: 500px;
height: 500px;
border-radius: 50%;
border: 10px solid #333;
margin: 20px auto;
position: relative;
overflow: hidden;
}
.segment {
position: absolute;
width: 50%;
height: 50%;
background-color: #f1c40f;
transform-origin: 100% 100%;
text-align: right;
padding-right: 10px;
font-size: 12px;
color: #000;
}
#spinBtn {
padding: 10px 30px;
font-size: 18px;
margin-top: 20px;
cursor: pointer;
}
#pointer {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 30px solid red;
margin: auto;
position: relative;
top: -520px;
}
🎡 Spin Wheel of Indian States 🇮🇳
SPIN
const states = [
“Andhra Pradesh”, “Arunachal Pradesh”, “Assam”, “Bihar”, “Chhattisgarh”, “Goa”,
“Gujarat”, “Haryana”, “Himachal Pradesh”, “Jharkhand”, “Karnataka”, “Kerala”,
“Madhya Pradesh”, “Maharashtra”, “Manipur”, “Meghalaya”, “Mizoram”, “Nagaland”,
“Odisha”, “Punjab”, “Rajasthan”, “Sikkim”, “Tamil Nadu”, “Telangana”,
“Tripura”, “Uttar Pradesh”, “Uttarakhand”, “West Bengal”
];
const wheel = document.getElementById(‘wheel’);
const result = document.getElementById(‘result’);
const segmentAngle = 360 / states.length;
states.forEach((state, i) => {
const segment = document.createElement(‘div’);
segment.className = ‘segment’;
segment.style.transform = `rotate(${i * segmentAngle}deg) skewY(${90 – segmentAngle}deg)`;
segment.style.backgroundColor = `hsl(${i * 13}, 80%, 60%)`;
segment.innerText = state;
wheel.appendChild(segment);
});
let angle = 0;
document.getElementById(‘spinBtn’).onclick = () => {
const spinAngle = 3600 + Math.floor(Math.random() * 360);
angle += spinAngle;
wheel.style.transition = ‘transform 5s ease-out’;
wheel.style.transform = `rotate(${angle}deg)`;
const selectedIndex = Math.floor(((360 – (angle % 360)) % 360) / segmentAngle);
setTimeout(() => {
result.innerText = `🎉 Selected State: ${states[selectedIndex]} 🎉`;
}, 5200);
};