колесо фортуны на JS + php

Возникла проблема при разработке колеса фортуны. Сейчас на колесе неправильно отображается секция с призом. То есть - на секцию должна показать стрелочка, которая отрисована в css. Как рассчитать так, чтобы после отработки алгоритма на сервере, к клиенту пришёл не только в виде сообщения, как сейчас, реализовано, но и отобразился на колесе верно?
Код js

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const spinButton = document.getElementById('spinButton');
const result = document.getElementById('result');
const prizeImg = document.getElementById('prize-img');
const prizeImageDiv = document.getElementById('prize-image');
let isSpinning = false;
let remainingSpins = parseInt(document.getElementById('remainingSpins').textContent);

const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = centerX;

const numberOfSegments = allPrizes.length; 
const anglePerSegment = (2 * Math.PI) / numberOfSegments;

// Смещение, чтобы остановиться в середине сегмента
const offsetAngle = anglePerSegment / 2;

const backgroundImage = new Image();
backgroundImage.src = '/images/wheel-background.png';  

backgroundImage.onload = () => {
    drawWheel(allPrizes);
};

backgroundImage.onerror = () => {
    console.error('Ошибка при загрузке фонового изображения');
};

function drawWheel(prizes, currentAngle = 0) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);

    for (let i = 0; i < numberOfSegments; i++) {
        const startAngle = currentAngle + i * anglePerSegment;
        const endAngle = startAngle + anglePerSegment;

        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.arc(centerX, centerY, radius, startAngle, endAngle);
        ctx.fillStyle = i % 2 === 0 ? 'rgba(251, 197, 49, 0.3)' : 'rgba(243, 156, 18, 0.3)';
        ctx.fill();
        ctx.closePath();

        ctx.save();
        ctx.translate(centerX, centerY);
        ctx.rotate(startAngle + anglePerSegment / 2);
        ctx.textAlign = "right";
        ctx.fillStyle = "#2c3e50";
        ctx.font = 'bold 11px sans-serif';
        ctx.fillText(prizes[i].prize_name, radius - 20, 10); // Отображаем название приза
        ctx.restore();
    }

    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
    ctx.lineWidth = 5;
    ctx.strokeStyle = '#F9A602';
    ctx.stroke();
    ctx.closePath();

    drawArrow();
}


// Функция для отрисовки стрелки
function drawArrow() {
    const arrowSize = 30;

    ctx.beginPath();
    ctx.moveTo(centerX - arrowSize, centerY - radius - arrowSize - 10);
    ctx.lineTo(centerX + arrowSize, centerY - radius - arrowSize - 10);
    ctx.lineTo(centerX, centerY - radius - 10);
    ctx.closePath();
    ctx.fillStyle = '#F9A602';
    ctx.fill();
}

// Функция для вычисления сегмента, который остановился в верхней части (на стрелке)
function getWinningSegment(currentAngle) {
    const adjustedAngle = (currentAngle % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
    const winningIndex = Math.floor((adjustedAngle / anglePerSegment) % numberOfSegments);
    return winningIndex;
}

// Функция для вращения колеса
function spinWheel() {
    if (isSpinning || remainingSpins <= 0) return;

    drawWheel(allPrizes, 0);

    isSpinning = true;

    const rotations = Math.floor(Math.random() * 5) + 3;
    const randomSegment = Math.floor(Math.random() * numberOfSegments);

    // Финальный угол будет рассчитан так, чтобы указатель остановился на середине выбранного сегмента
    const finalAngle = randomSegment * anglePerSegment + offsetAngle;
    const totalAngle = rotations * 2 * Math.PI + finalAngle;

    let currentAngle = 0;
    const spinTime = 5000;
    const startTime = Date.now();

    function animate() {
        const elapsed = Date.now() - startTime;
        const easeOut = t => t * (2 - t);
        currentAngle = easeOut(elapsed / spinTime) * totalAngle;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.save();
        ctx.translate(centerX, centerY);
        ctx.rotate(currentAngle);
        ctx.translate(-centerX, -centerY);
        drawWheel(allPrizes, currentAngle);
        ctx.restore();

        if (elapsed < spinTime) {
            requestAnimationFrame(animate);
        } else {
            isSpinning = false;

            // Отправка запроса на сервер для обновления информации и получения результата
            fetch('spin.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ action: 'spin' })  // Тело запроса может быть полезным, если нужно передавать дополнительные данные
            })
            .then(response => response.json())
            .then(data => {
                console.log('Ответ от сервера:', data);
                if (data.status === 'success') {
                    result.textContent = `Вы выиграли: ${data.real_prize}!`;
                    prizeImg.src = data.prize_image_url;
                    prizeImageDiv.style.display = 'block';

                    // Обновляем количество оставшихся прокруток
                    console.log('Старое значение remainingSpins:', remainingSpins);
                    remainingSpins = data.remaining_spins;
                    console.log('Новое значение remainingSpins:', remainingSpins);
                    document.getElementById('remainingSpins').textContent = remainingSpins;

                    if (remainingSpins <= 0) {
                        spinButton.disabled = true;
                    }
                } else {
                    alert(data.message);
                }
            })
            .catch(error => {
                console.error('Ошибка получения результата от сервера:', error);
                isSpinning = false; // Разрешаем повторить попытку, если был сбой
            });
        }
    }

    animate();
}

spinButton.addEventListener('click', spinWheel);

Ответы (0 шт):