Skip to content

Instantly share code, notes, and snippets.

@housamz
Last active October 23, 2024 09:22
Show Gist options
  • Save housamz/256fcaae7211cce040352e8f8dd6a9ff to your computer and use it in GitHub Desktop.
Save housamz/256fcaae7211cce040352e8f8dd6a9ff to your computer and use it in GitHub Desktop.
Raffle Draw Lucky wheel
.controls-container
h3#headline Insert Names Here
small#subheader (separated by commas or new lines)
span#counter
textarea#names(rows="10", cols="40").
Ben, David, Declan, Housam, Jeongtae, Kevin, Ming, Robin
small#counter
button#spin Spin The Wheel
button#remove Remove Winner
.container
#wheel
let names = [],
colors = [],
sliceDeg,
speed = 0,
slowDownRand = 0,
ctx,
width,
center,
deg,
isStopped = false,
lock = false,
winner,
namesContainer = document.getElementById("names");
let shuffle = (array) => {
for (let i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
};
let checkTextArea = () => {
names = namesContainer.value
.replace(/\n/g, ",") // convert line breaks to commas
.replace(/,\s*$/, "") // remove last comma
.split(",")
.map(function (item) {
return item.trim();
});
document.getElementById("counter").innerText = names.length + " names";
sliceDeg = 360 / names.length;
};
let fillColors = () => {
let color;
while (colors.length < names.length) {
do {
color = Math.floor(Math.random() * 1000000 + 1);
} while (colors.indexOf(color) >= 0);
colors.push("#" + ("000000" + color.toString(16)).slice(-6));
}
};
let rand = (min, max) => {
return Math.random() * (max - min) + min;
};
deg = rand(0, 360);
let deg2rad = (deg) => {
return (deg * Math.PI) / 180;
};
let drawSlice = (deg, color) => {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
};
let drawText = (deg, text) => {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = "bold 20px 'Open Sans', sans-serif";
ctx.fillText(text, center - 20, center / (names.length * 2));
ctx.restore();
};
let drawImg = () => {
width =
(names.length + 2) * 30 > 300 ? (names.length + 2) * 30 : 300;
canvas = document.createElement("canvas");
document.getElementById("wheel").innerHTML = "";
document.getElementById("wheel").appendChild(canvas);
ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = width;
center = width / 2;
fillColors();
ctx.clearRect(0, 0, width, width);
for (let i = 0; i < names.length; i++) {
drawSlice(deg, colors[i]);
drawText(deg + sliceDeg / 2, names[i]);
deg += sliceDeg;
}
};
let anim = () => {
deg += speed;
deg %= 360;
// Increment speed
if (!isStopped && speed < 3) {
speed = speed + 1 * 0.1;
}
// Decrement Speed
if (isStopped) {
if (!lock) {
lock = true;
slowDownRand = rand(0.2, 0.9);
}
speed = speed > 0.2 ? (speed *= slowDownRand) : 0;
}
// Stopped!
if (lock && !speed) {
let ai = Math.floor(((360 - deg - 90) % 360) / sliceDeg); // deg 2 Array Index
ai = (names.length + ai) % names.length; // Fix negative index
winner = ai;
return alert("You got:\n" + names[ai]); // Get Array Item from end Degree
}
drawImg();
window.requestAnimationFrame(anim);
};
let reset = () => {
shuffle(names);
sliceDeg = 360 / names.length;
drawImg();
};
document.getElementById("spin").addEventListener(
"mousedown",
() => {
anim();
setTimeout(function () {
isStopped = true;
}, 1900);
setTimeout(function () {
speed = 0;
slowDownRand = 0;
isStopped = false;
lock = false;
}, 3000);
},
false
);
namesContainer.addEventListener(
"input",
() => {
checkTextArea();
reset();
},
false
);
document.getElementById("remove").addEventListener(
"mousedown",
() => {
names.splice(winner, 1);
reset();
},
false
);
checkTextArea();
drawImg();
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap");
body,
textarea,
button {
font-family: "Open Sans", sans-serif;
font-size: 18px;
}
body {
display: flex;
justify-content: center;
padding-top: 50px;
}
.controls-container {
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 100;
background-color: white;
padding: 40px 40px 0 40px;
}
#headline {
margin: 0;
}
#subheader {
display: block;
margin-bottom: 10px;
}
textarea {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
display: block;
}
button {
font-weight: bold;
background-color: #027bc7;
border-color: transparent;
color: white;
border-radius: 5px;
margin: 10px 0;
padding: 10px 20px;
&:nth-of-type(2) {
background-color: #ca0d30;
float: right;
}
}
#wheel {
position: relative;
overflow: hidden;
margin: 0 0 0 60px;
&:after {
content: "";
background: red;
border: 2px solid white;
position: absolute;
top: -7px;
left: 50%;
width: 10px;
height: 10px;
margin-left: -7px;
transform: rotate(45deg);
}
}
#counter{
float:right
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment