<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Country Capital Spin Wheel</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
display: flex; flex-direction: column; align-items: center; justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
font-family: 'Segoe UI', system-ui, sans-serif; color: #fff;
gap: 20px; padding: 20px;
}
h1 {
font-size: 32px; font-weight: 800; text-align: center;
background: linear-gradient(90deg, #e94560, #ff6b6b, #feca57);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
p.subtitle { color: #a0a0c0; font-size: 16px; }
.wheel-wrapper {
position: relative; display: flex; flex-direction: column; align-items: center; gap: 20px;
}
.pointer {
position: absolute; top: -10px; left: 50%; transform: translateX(-50%); z-index: 10;
width: 0; height: 0; border-left: 18px solid transparent; border-right: 18px solid transparent;
border-top: 28px solid #e94560; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
}
#wheel-container {
position: relative; width: 340px; height: 340px; border-radius: 50%;
box-shadow: 0 0 40px rgba(233, 69, 96, 0.3), inset 0 0 20px rgba(0,0,0,0.3);
border: 4px solid #e94560;
}
canvas { border-radius: 50%; cursor: pointer; }
.hub {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 52px; height: 52px; background: linear-gradient(135deg, #e94560, #c73e54);
border-radius: 50%; box-shadow: 0 4px 15px rgba(0,0,0,0.4);
display: flex; align-items: center; justify-content: center; font-size: 22px;
z-index: 5; border: 3px solid #fff;
}
#spin-btn {
padding: 16px 56px; font-size: 20px; font-weight: 700; color: #fff;
background: linear-gradient(135deg, #e94560, #c73e54); border: none;
border-radius: 50px; cursor: pointer;
box-shadow: 0 6px 20px rgba(233, 69, 96, 0.4);
transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 2px;
}
#spin-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(233, 69, 96, 0.5); }
#spin-btn:active { transform: translateY(1px); }
#spin-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
#result-card {
display: none; flex-direction: column; align-items: center; gap: 8px;
padding: 24px 40px; background: rgba(255,255,255,0.08); backdrop-filter: blur(10px);
border-radius: 16px; border: 1px solid rgba(255,255,255,0.1);
min-width: 300px; text-align: center;
}
#result-card.show { display: flex; animation: fadeIn 0.5s ease; }
.emoji { font-size: 52px; animation: bounce 0.6s ease; }
#result-country { font-size: 24px; font-weight: 700; color: #feca57; }
.label { font-size: 14px; color: #a0a0c0; }
#result-capital { font-size: 30px; font-weight: 800; color: #e94560; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes bounce { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.3); } }
@media (max-width: 480px) {
#wheel-container { width: 280px; height: 280px; }
h1 { font-size: 24px; }
}
</style>
</head>
<body>
<h1>🌍 Country Capital Wheel</h1>
<p class="subtitle">Spin to discover a world capital!</p>
<div class="wheel-wrapper">
<div class="pointer"></div>
<div id="wheel-container">
<canvas id="wheel" width="340" height="340"></canvas>
<div class="hub">🎯</div>
</div>
<button id="spin-btn">SPIN</button>
</div>
<div id="result-card">
<div class="emoji">🎉</div>
<div id="result-country"></div>
<div class="label">Capital:</div>
<div id="result-capital"></div>
</div>
<script>
const canvas = document.getElementById('wheel');
const ctx = canvas.getContext('2d');
const spinBtn = document.getElementById('spin-btn');
const resultCard = document.getElementById('result-card');
const resultCountry = document.getElementById('result-country');
const resultCapital = document.getElementById('result-capital');
const data = [
{ country: "France", capital: "Paris" }, { country: "Japan", capital: "Tokyo" },
{ country: "Brazil", capital: "Brasília" }, { country: "Egypt", capital: "Cairo" },
{ country: "Australia", capital: "Canberra" }, { country: "India", capital: "New Delhi" },
{ country: "Canada", capital: "Ottawa" }, { country: "Germany", capital: "Berlin" },
{ country: "Italy", capital: "Rome" }, { country: "Mexico", capital: "Mexico City" },
{ country: "Russia", capital: "Moscow" }, { country: "South Korea", capital: "Seoul" }
];
const colors = [
'#e94560', '#0f3460', '#533483', '#f39422', '#16a085',
'#2980b9', '#8e44ad', '#c0392b', '#27ae60', '#d35400',
'#2c3e50', '#e74c3c'
];
const numSegments = data.length;
const arcSize = (2 * Math.PI) / numSegments;
let currentAngle = 0;
let isSpinning = false;
function drawWheel() {
const cx = canvas.width / 2, cy = canvas.height / 2;
const radius = canvas.width / 2 - 4;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < numSegments; i++) {
const angle = currentAngle + i * arcSize;
ctx.beginPath(); ctx.moveTo(cx, cy);
ctx.arc(cx, cy, radius, angle, angle + arcSize); ctx.closePath();
ctx.fillStyle = colors[i % colors.length]; ctx.fill();
ctx.strokeStyle = '#1a1a2e'; ctx.lineWidth = 2; ctx.stroke();
ctx.save(); ctx.translate(cx, cy); ctx.rotate(angle + arcSize / 2);
ctx.textAlign = "right"; ctx.fillStyle = "#fff";
ctx.font = "bold 14px 'Segoe UI', sans-serif";
ctx.fillText(data[i].country, radius - 18, 5); ctx.restore();
}
ctx.beginPath(); ctx.arc(cx, cy, radius * 0.15, 0, 2 * Math.PI);
ctx.strokeStyle = 'rgba(255,255,255,0.2)'; ctx.lineWidth = 2; ctx.stroke();
}
function spinWheel() {
if (isSpinning) return;
isSpinning = true; spinBtn.disabled = true;
resultCard.classList.remove('show');
const spins = 5 + Math.random() * 3;
const extraAngle = Math.random() * 2 * Math.PI;
const targetAngle = currentAngle + spins * 2 * Math.PI + extraAngle;
const duration = 4000;
const startTime = performance.now();
const startAngle = currentAngle;
function animate(now) {
const elapsed = now - startTime;
const progress = Math.min(elapsed / duration, 1);
const ease = 1 - Math.pow(1 - progress, 3);
currentAngle = startAngle + (targetAngle - startAngle) * ease;
drawWheel();
if (progress < 1) requestAnimationFrame(animate);
else { isSpinning = false; spinBtn.disabled = false; showResult(); }
}
requestAnimationFrame(animate);
}
function showResult() {
let normalized = (3 * Math.PI / 2 - currentAngle) % (2 * Math.PI);
if (normalized < 0) normalized += 2 * Math.PI;
const index = Math.floor(normalized / arcSize) % numSegments;
const winner = data[index];
resultCountry.textContent = winner.country;
resultCapital.textContent = winner.capital;
resultCard.classList.add('show');
}
spinBtn.addEventListener('click', spinWheel);
drawWheel();
</script>
</body>
</html>
build live link that I can share