mirror of
https://github.com/kevinveenbirkenbach/roulette-wheel.git
synced 2024-11-21 17:51:05 +01:00
rotation of item's names fix
This commit is contained in:
parent
559865834a
commit
861b9e34af
39
app.css
39
app.css
@ -5,7 +5,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas{
|
canvas{
|
||||||
margin-left: 5rem;
|
|
||||||
height: 50rem;
|
height: 50rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,23 +43,17 @@ ul {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-delete {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
.light-dark-mode {
|
.light-dark-mode {
|
||||||
float: right;
|
float: right;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remove-all-items-button {
|
|
||||||
width: 5.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.roulette-wheel {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
width: 24rem;
|
width: 24rem;
|
||||||
}
|
}
|
||||||
@ -74,11 +67,18 @@ ul {
|
|||||||
height: 3rem;
|
height: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-all-items-button {
|
||||||
|
width: 5.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
.item-delete {
|
.roulette-wheel {
|
||||||
width: 1rem;
|
position: absolute;
|
||||||
height: 1rem;
|
top: 50%;
|
||||||
float: right;
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: -1;
|
||||||
|
margin-left: 5rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.open-close-menu {
|
.open-close-menu {
|
||||||
@ -86,6 +86,11 @@ ul {
|
|||||||
justify-content: right;
|
justify-content: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.winner {
|
||||||
|
font-size: 32;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 940px) {
|
@media screen and (max-width: 940px) {
|
||||||
canvas{
|
canvas{
|
||||||
margin-top: 5rem;
|
margin-top: 5rem;
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
</div> -->
|
</div> -->
|
||||||
<p class="counter"></p>
|
<p class="counter"></p>
|
||||||
<label for="new-item">Item name</label>
|
<label for="new-item">Item name</label>
|
||||||
<input name="new-item" minlength="1" maxlength="32" />
|
<input name="new-item" minlength="1" maxlength="20" />
|
||||||
<button class="add-item-button">Add</button>
|
<button class="add-item-button">Add</button>
|
||||||
<button class="remove-all-items-button">Remove all</button>
|
<button class="remove-all-items-button">Remove all</button>
|
||||||
<ul class="menu-item-list"></ul>
|
<ul class="menu-item-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="roulette-wheel">
|
<div class="roulette-wheel">
|
||||||
|
<div class="winner"></div>
|
||||||
<canvas></canvas>
|
<canvas></canvas>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
100
src/app.ts
100
src/app.ts
@ -28,13 +28,14 @@ const modeEl = lightDarkModeEl.querySelector("img")! as HTMLImageElement;
|
|||||||
const canvasWrapper = document.getElementsByClassName(
|
const canvasWrapper = document.getElementsByClassName(
|
||||||
"roulette-wheel"
|
"roulette-wheel"
|
||||||
)[0]! as HTMLDivElement;
|
)[0]! as HTMLDivElement;
|
||||||
|
const winnerEl = document.getElementsByClassName('winner')[0]! as HTMLDivElement;
|
||||||
|
|
||||||
const MAXIMUM_SIZE = 16;
|
const MAXIMUM_SIZE = 16;
|
||||||
canvasEl.width = canvasWrapper.offsetWidth;
|
canvasEl.width = canvasWrapper.offsetWidth;
|
||||||
canvasEl.height = canvasWrapper.offsetHeight;
|
canvasEl.height = canvasWrapper.offsetHeight;
|
||||||
const x = canvasEl.width / 2;
|
const x = canvasEl.width / 2;
|
||||||
const y = canvasEl.height / 2;
|
const y = canvasEl.height / 2;
|
||||||
const radius = canvasEl.height / 2;
|
const radius = canvasEl.height / 2 - 5;
|
||||||
const animationFPSRate = 30;
|
const animationFPSRate = 30;
|
||||||
|
|
||||||
counterEl.textContent = `0/${MAXIMUM_SIZE}`;
|
counterEl.textContent = `0/${MAXIMUM_SIZE}`;
|
||||||
@ -158,9 +159,9 @@ function lightDarkMode() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrowImage = document.createElement('img');
|
const arrowImage = document.createElement("img");
|
||||||
arrowImage.src = 'static/arrow-down.png';
|
arrowImage.src = "static/arrow-down.png";
|
||||||
arrowImage.alt = 'arrow';
|
arrowImage.alt = "arrow";
|
||||||
|
|
||||||
function drawRouletteWheel(angle: number) {
|
function drawRouletteWheel(angle: number) {
|
||||||
const segmentWidth = 360 / items.length;
|
const segmentWidth = 360 / items.length;
|
||||||
@ -168,13 +169,23 @@ function drawRouletteWheel(angle: number) {
|
|||||||
let endAngle = segmentWidth + startAngle;
|
let endAngle = segmentWidth + startAngle;
|
||||||
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
|
|
||||||
// let xtemp = x + Math.cos(totalAngle/2) * radius/2;
|
// let xtemp = x + Math.cos(totalAngle/2) * radius/2;
|
||||||
// let ytemp = y + Math.sin(totalAngle/2) * radius/2;
|
// let ytemp = y + Math.sin(totalAngle/2) * radius/2;
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(x + radius + 50, y);
|
||||||
|
ctx.lineTo(0, -20);
|
||||||
|
ctx.lineTo(0, 20);
|
||||||
|
ctx.lineTo(-50, 0);
|
||||||
|
ctx.fillStyle = 'white';
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
|
||||||
|
ctx.stroke();
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineTo(x, y)
|
ctx.lineTo(x, y);
|
||||||
ctx.font = 'bold 24px verdana, sans-serif';
|
ctx.font = "bold 24px verdana, sans-serif";
|
||||||
ctx.arc(
|
ctx.arc(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
@ -183,14 +194,33 @@ function drawRouletteWheel(angle: number) {
|
|||||||
(endAngle * Math.PI) / 180,
|
(endAngle * Math.PI) / 180,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
ctx.fillText(itemsList.items[i].name, x + Math.cos(segmentWidth * i ) * radius / 2, y + Math.sin(segmentWidth * i + angle) * radius / 2 );
|
ctx.lineTo(x, y);
|
||||||
ctx.lineTo(x, y)
|
|
||||||
ctx.fillStyle = itemsList.items[i].color;
|
ctx.fillStyle = itemsList.items[i].color;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
ctx.save();
|
||||||
|
ctx.fillStyle = "black";
|
||||||
|
const text = itemsList.items[i].name;
|
||||||
|
if (items.length > 1) {
|
||||||
|
const xT =
|
||||||
|
x +
|
||||||
|
(Math.cos((startAngle + segmentWidth / 2) * Math.PI / 180) * radius) /
|
||||||
|
2;
|
||||||
|
const xY =
|
||||||
|
y +
|
||||||
|
(Math.sin((startAngle + segmentWidth / 2) * Math.PI / 180) * radius) /
|
||||||
|
2;
|
||||||
|
ctx.translate(xT, xY);
|
||||||
|
console.log(totalAngle);
|
||||||
|
ctx.rotate(Math.PI / items.length + Math.PI/180 * startAngle);
|
||||||
|
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
ctx.fillText(text, x, y);
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
if (items.length !== 1) {
|
if (items.length !== 1) {
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
ctx.drawImage(arrowImage, x - 32, -32, 64, 64);
|
|
||||||
startAngle += segmentWidth;
|
startAngle += segmentWidth;
|
||||||
endAngle += segmentWidth;
|
endAngle += segmentWidth;
|
||||||
// xtemp += Math.cos(totalAngle/2) * radius/2;
|
// xtemp += Math.cos(totalAngle/2) * radius/2;
|
||||||
@ -199,46 +229,46 @@ function drawRouletteWheel(angle: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let guessItemIndex = Math.floor(Math.random() * items.length);
|
let guessItemIndex = Math.floor(Math.random() * items.length);
|
||||||
let segmentAngle = 360 / items.length;
|
let segmentAngle = 360 / items.length;
|
||||||
const rotations = 3;
|
const rotations = 1;
|
||||||
let maxAngle = 360 * rotations + segmentAngle * guessItemIndex;
|
let maxAngle = 360 * rotations + segmentAngle * guessItemIndex;
|
||||||
let angleSpeed = 0;
|
let angleSpeed = 0;
|
||||||
let totalAngle = 0;
|
let totalAngle = 0;
|
||||||
let animationId: number | null;
|
let animationId: number | null;
|
||||||
let startAngle = 1;
|
let startAngle = 2;
|
||||||
// const maxAngleSpeed = segmentAngle;
|
// const maxAngleSpeed = segmentAngle;
|
||||||
|
|
||||||
function startRoulette(){
|
function startRoulette() {
|
||||||
if(animationId){
|
if (animationId) {
|
||||||
//resetRouletteAnimation();
|
//resetRouletteAnimation();
|
||||||
}else{
|
} else {
|
||||||
guessItemIndex = Math.floor(Math.random() * items.length);
|
guessItemIndex = Math.floor(Math.random() * items.length);
|
||||||
console.log(guessItemIndex);
|
console.log(guessItemIndex);
|
||||||
segmentAngle = 360 / items.length;
|
segmentAngle = 360 / items.length;
|
||||||
maxAngle = 360 * rotations + ((items.length - 1) - guessItemIndex) * segmentAngle + Math.random() * segmentAngle;
|
maxAngle =
|
||||||
|
360 * rotations +
|
||||||
|
(items.length - 1 - guessItemIndex) * segmentAngle +
|
||||||
|
Math.random() * segmentAngle;
|
||||||
beginAnimateRoulette();
|
beginAnimateRoulette();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginAnimateRoulette(){
|
function beginAnimateRoulette() {
|
||||||
if(totalAngle < maxAngle){
|
if (totalAngle < maxAngle) {
|
||||||
drawRouletteWheel(angleSpeed);
|
drawRouletteWheel(angleSpeed);
|
||||||
angleSpeed += startAngle;
|
angleSpeed += startAngle;
|
||||||
totalAngle += startAngle;
|
totalAngle += startAngle;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
animationId = window.requestAnimationFrame(beginAnimateRoulette);
|
animationId = window.requestAnimationFrame(beginAnimateRoulette);
|
||||||
}, 1000 / animationFPSRate);
|
}, 1000 / animationFPSRate);
|
||||||
|
} else {
|
||||||
}else{
|
window.cancelAnimationFrame(animationId!);
|
||||||
window.cancelAnimationFrame(animationId!)
|
animationId = null;
|
||||||
animationId = null;
|
angleSpeed = 1;
|
||||||
angleSpeed = 1;
|
totalAngle = 0;
|
||||||
totalAngle = 0;
|
winnerEl.textContent = `Winner: ${itemsList.items[guessItemIndex].name}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// function resetRouletteAnimation(){
|
// function resetRouletteAnimation(){
|
||||||
@ -252,4 +282,4 @@ function beginAnimateRoulette(){
|
|||||||
// delta = 0.2;
|
// delta = 0.2;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
canvasEl.addEventListener('click', startRoulette);
|
canvasEl.addEventListener("click", startRoulette);
|
||||||
|
BIN
static/MFI-LIC-275177-1.pdf
Normal file
BIN
static/MFI-LIC-275177-1.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user