const canvas = document.getElementById("wheel"); const ctx = canvas.getContext("2d"); const spinBtn = document.getElementById("spinBtn"); const resultBox = document.getElementById("resultBox"); const resultText = document.getElementById("resultText"); const rewards = [ "1K Followers", "2K Followers", "10K Followers", "20K Views", "50K Views", "100K Views" ]; // Fixed Prize (can be set server-side) const fixedPrize = "20K Views"; let centerX = 0; let centerY = 0; let radius = 0; let arc = (2 * Math.PI) / rewards.length; let currentAngle = 0; function setCanvasSize() { // Match canvas pixel size to CSS size for crisp rendering on all DPRs const rect = canvas.getBoundingClientRect(); const devicePixelRatioSafe = Math.max(1, Math.floor(window.devicePixelRatio || 1)); canvas.width = Math.floor(rect.width * devicePixelRatioSafe); canvas.height = Math.floor(rect.height * devicePixelRatioSafe); centerX = canvas.width / 2; centerY = canvas.height / 2; radius = Math.min(centerX, centerY); ctx.setTransform(1, 0, 0, 1, 0, 0); drawWheel(); } function drawWheel() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < rewards.length; i++) { const startAngle = i * arc + currentAngle; const endAngle = startAngle + arc; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.fillStyle = i % 2 === 0 ? "#ff4d6d" : "#ff9f1c"; ctx.arc(centerX, centerY, radius, startAngle, endAngle); ctx.closePath(); ctx.fill(); // Text ctx.save(); ctx.translate(centerX, centerY); ctx.rotate(startAngle + arc / 2); ctx.textAlign = "right"; ctx.fillStyle = "#fff"; ctx.font = `${Math.max(12, Math.floor(radius * 0.07))}px Arial`; ctx.fillText(rewards[i], radius * 0.78, 6); ctx.restore(); } // Center hub ctx.beginPath(); ctx.arc(centerX, centerY, Math.max(8, radius * 0.08), 0, Math.PI * 2); ctx.fillStyle = "#22262c"; ctx.fill(); ctx.lineWidth = Math.max(2, radius * 0.015); ctx.strokeStyle = "#444b57"; ctx.stroke(); } function spinWheel() { spinBtn.disabled = true; const prizeIndex = rewards.indexOf(fixedPrize); const targetAngle = (Math.PI * 3 / 2) - (prizeIndex * arc + arc / 2); // align prize to top pointer const fullSpins = 5 * 2 * Math.PI; const finalAngle = fullSpins + normalizeAngle(targetAngle - currentAngle); const durationMs = 5000; let startTs = null; const startAngle = currentAngle; function animate(ts) { if (!startTs) startTs = ts; const elapsed = ts - startTs; const eased = easeOutCubic(Math.min(elapsed / durationMs, 1)); currentAngle = startAngle + finalAngle * eased; drawWheel(); if (elapsed < durationMs) { requestAnimationFrame(animate); } else { // Snap to final position precisely currentAngle = startAngle + finalAngle; drawWheel(); showResult(fixedPrize); } } requestAnimationFrame(animate); } function normalizeAngle(angle) { const twoPi = Math.PI * 2; return ((angle % twoPi) + twoPi) % twoPi; } function easeOutCubic(t) { return 1 - Math.pow(1 - t, 3); } function showResult(prize) { resultBox.classList.remove("hidden"); resultText.textContent = `🎉 Congratulations! You won: ${prize}`; } function redirectToClaim() { window.location.href = "../claim/claim.html"; } window.addEventListener("resize", setCanvasSize); // Initialize sizing after the canvas is in layout setTimeout(setCanvasSize, 0); spinBtn.addEventListener("click", spinWheel);