instagram / likes /spin /script.js
abeea's picture
Upload 6 files
03834ad verified
Raw
History Blame Contribute Delete
3.65 kB
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);