const sectors = [
{color:"#426d7a", label:"Rent"},
{color:"#00a6fa", label:"Services"},
{color:"#f8c200", label:"Hotel"},
{color:"#409f21", label:"Utility"},
{color:"#ff4fa1", label:"Robbery"},
{color:"#45717c", label:"Bankrupt"},
{color:"#ff5001", label:"Death"},
];
// Generate random float in range min-max:
const rand = (m, M) => Math.random() * (M - m) + m;
const tot = sectors.length;
const elSpin = document.querySelector("#spin");
const ctx = document.querySelector("#wheel").getContext`2d`;
const dia = ctx.canvas.width;
const rad = dia / 2;
const PI = Math.PI;
const TAU = 2 * PI;
const arc = TAU / sectors.length;
const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard
const angVelMin = 0.002; // Below that number will be treated as a stop
let angVelMax = 0; // Random ang.vel. to acceletare to
let angVel = 0; // Current angular velocity
let ang = 0; // Angle rotation in radians
let isSpinning = false;
let isAccelerating = false;
//* Get index of current sector */
const getIndex = () => {
console.log(Math.floor(tot - ang / TAU * tot) % tot)
return Math.floor(tot - ang / TAU * tot) % tot;
}
// console.log(getIndex())
//* Draw sectors and prizes texts to canvas */
const drawSector = (sector, i) => {
const ang = arc * i;
ctx.save();
// COLOR
ctx.beginPath();
ctx.fillStyle = sector.color;
ctx.moveTo(rad, rad);
ctx.arc(rad, rad, rad, ang, ang + arc);
ctx.lineTo(rad, rad);
ctx.fill();
// TEXT
ctx.translate(rad, rad);
ctx.rotate(ang + arc / 2);
ctx.textAlign = "right";
ctx.fillStyle = "#000";
ctx.font = "bold 30px sans-serif";
ctx.fillText(sector.label, rad - 10, 10);
//
ctx.restore();
};
//* CSS rotate CANVAS Element */
const rotate = () => {
const sector = sectors[getIndex()];
ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`;
elSpin.textContent = !angVel ? "SPIN" : sector.label;
elSpin.style.background = sector.color;
return sector.label
};
const frame = () => {
if (!isSpinning) return;
if (angVel >= angVelMax) isAccelerating = false;
// Accelerate
if (isAccelerating) {
angVel ||= angVelMin; // Initial velocity kick
angVel *= 1.06; // Accelerate
}
// Decelerate
else {
isAccelerating = false;
angVel *= friction; // Decelerate by friction
// SPIN END:
if (angVel < angVelMin) {
isSpinning = false;
angVel = 0;
alert(rotate())
}
}
ang += angVel; // Update angle
ang %= TAU; // Normalize angle
rotate(); // CSS rotate!
};
const engine = () => {
frame();
requestAnimationFrame(engine)
};
elSpin.addEventListener("click", () => {
if (isSpinning) return;
isSpinning = true;
isAccelerating = true;
angVelMax = rand(0.25, 0.40);
});
// INIT!
sectors.forEach(drawSector);
rotate(); // Initial rotation
engine(); // Start engine!