Как мне desarrollar такую логику?

Всем привет! <br/> Я разрабатываю проект, который будет напоминать кейс-опенер. <br/> Однако мне не удается реализовать логику, которая определяла бы, как маркер будет располагаться над выигрышным предметом. <br/> Можете помочь мне создать алгоритм, который обеспечит точное размещение маркера над элементом, соответствующим результату (resultText)? <br/> Вот мой JS код: <br/> <pre><code class="javascript">const items = [
        { name: "100 000", reward: "100000_sr", chance: 5 },
        { name: "VIP (14 дней)", reward: "14_vipsr", chance: 3 },
        { name: "1000 Алмазов", reward: "1000_az", chance: 2 },
        { name: "75 000 ", reward: "75000_sr", chance: 10 },
        { name: "VIP SILVER (7 дней)", reward: "7_sl", chance: 8 },
        { name: "500 Алмазов", reward: "500_az", chance: 7 },
        { name: "1000 Пыли", reward: "1000_ds", chance: 6 },
        { name: "25 000 ", reward: "25000_sr", chance: 15 },
        { name: "200 Алмазов", reward: "200_az", chance: 15 },
        { name: "300 Пыли", reward: "300_ds", chance: 15 },
        { name: "Ускорение (3 lvl)", reward: "3_boost", chance: 10 },
        { name: "Улучшение (3 lvl)", reward: "3_imp", chance: 10 },
        { name: "VIP SILVER (2 дня)", reward: "2_sl", chance: 10 },
        { name: "10 000 ", reward: "10000_sr", chance: 20 },
        { name: "5 000 ", reward: "5000_sr", chance: 20 },
        { name: "100 Алмазов", reward: "100_az", chance: 20 },
        { name: "Ускорение (2 lvl)", reward: "2_boost", chance: 20 }
    ];

    const caseContainer = document.getElementById("caseContainer");
    const scrollingItems = document.getElementById("scrollingItems");
    const resultText = document.getElementById("resultText");
    const openCaseButton = document.getElementById("openCaseButton");
    const marker = docуме
  • 27 февраля 2025 г. 21:24
Ответы на вопрос 2
Для реализации логики, которая будет точно размещать маркер над выигрышным предметом в вашем проекте, вы можете следовать следующим шагам:

### 1. Определение выигрышного предмета
Сначала вам нужно будет определить, какой предмет является выигрышным. Предположим, что у вас есть функция, которая случайным образом выбирает элемент из массива `items` на основе заданных шансов.

### 2. Получение позиции элемента на экране
После того, как вы определили выигрышный элемент, вам нужно будет вычислить его позицию в контейнере `scrollingItems`, чтобы затем переместить маркер в это место.

### 3. Перемещение маркера
Используя вычисленную позицию элемента, вам нужно будет установить положение маркера.

Вот пример того, как это можно реализовать:

```javascript
// Функция для выбора выигрышного элемента
function getWinningItem() {
    const totalChance = items.reduce((sum, item) => sum + item.chance, 0);
    const random = Math.random() * totalChance;

    let cumulativeChance = 0;
    for (let item of items) {
        cumulativeChance += item.chance;
        if (random < cumulativeChance) {
            return item;
        }
    }
}

// Функция для показа маркера на выигрышном элементе
function showMarker(winningItem) {
    // Находим все элементы на экране, соответствующие предметам
    const itemElements = document.querySelectorAll('.item'); // Предполагается, что у вас есть класс 'item' для каждого предмета

    itemElements.forEach((element, index) => {
        if (items[index].name === winningItem.name) {
            const rect = element.getBoundingClientRect();
            const marker = document.getElementById("marker"); // Предполагаем, что у вас есть элемент с id 'marker'

            // Устанавливаем позицию маркера
            marker.style.left = `${rect.left + rect.width / 2}px`;
            marker.style.top = `${rect.top}px`;
            marker.style.display = 'block'; // Показываем маркер
        }
    });
}

// Привязка к кнопке открытия кейса
openCaseButton.addEventListener('click', () => {
    const winningItem = getWinningItem();
    resultText.innerText = `Вы выиграли: ${winningItem.name}`;
    showMarker(winningItem);
});
```

### Пояснения к коду:
1. **getWinningItem**: Эта функция определяет выигрыша на основе шансов, заданных для каждого предмета.
2. **showMarker**: Эта функция ищет элемент, соответствующий выигрышному предмету, и определяет его положение на экране с помощью `getBoundingClientRect()`. Затем маркер перемещается в это положение.
3. **Событие клика по кнопке**: После нажатия на кнопку "открыть кейс" вызывается функция, которая получает выигрышный элемент и показывает маркер.

### Примечание:
Убедитесь, что у вас есть соответствующий HTML-код с элементами, содержащими класс `item`, и элемент с ID `marker` для отображения маркера.
Привет, стоит ввести еще одну функцию positionMarker для такой задачи: 

const items = [
    { name: "100 000", reward: "100000_sr", chance: 5 },
    { name: "VIP (14 дней)", reward: "14_vipsr", chance: 3 },
    { name: "1000 Алмазов", reward: "1000_az", chance: 2 },
    { name: "75 000 ", reward: "75000_sr", chance: 10 },
    { name: "VIP SILVER (7 дней)", reward: "7_sl", chance: 8 },
    { name: "500 Алмазов", reward: "500_az", chance: 7 },
    { name: "1000 Пыли", reward: "1000_ds", chance: 6 },
    { name: "25 000 ", reward: "25000_sr", chance: 15 },
    { name: "200 Алмазов", reward: "200_az", chance: 15 },
    { name: "300 Пыли", reward: "300_ds", chance: 15 },
    { name: "Ускорение (3 lvl)", reward: "3_boost", chance: 10 },
    { name: "Улучшение (3 lvl)", reward: "3_imp", chance: 10 },
    { name: "VIP SILVER (2 дня)", reward: "2_sl", chance: 10 },
    { name: "10 000 ", reward: "10000_sr", chance: 20 },
    { name: "5 000 ", reward: "5000_sr", chance: 20 },
    { name: "100 Алмазов", reward: "100_az", chance: 20 },
    { name: "Ускорение (2 lvl)", reward: "2_boost", chance: 20 }
];

const caseContainer = document.getElementById("caseContainer");
const scrollingItems = document.getElementById("scrollingItems");
const resultText = document.getElementById("resultText");
const openCaseButton = document.getElementById("openCaseButton");
const marker = document.getElementById("marker");
let populatedItems = []; // Массив для хранения созданных предметов
let winningIndex = 0; // Индекс выигрышного предмета

function populateItems() {
    for (let i = 0; i < 151; i++) { // Создаем 151 предмет
        const item = items[i % items.length]; // Используем элементы из массива
        const div = document.createElement("div");
        div.className = "item";
        div.innerText = item.name;
        scrollingItems.appendChild(div);
        populatedItems.push(item); // Сохраняем предмет в массив
    }
}

function animateScroll(duration) {
    const itemWidth = scrollingItems.children[0].offsetWidth; // Ширина одного предмета
    const totalItems = scrollingItems.children.length;

    // Позиция, на которую нужно прокрутить, чтобы выигрышный элемент оказался под стрелкой
    const targetPosition = (winningIndex * itemWidth) - (caseContainer.offsetWidth / 2) + (itemWidth / 2); // Центрируем выигрышный элемент
    const scrollWidth = totalItems * itemWidth; // Общая ширина прокрутки
    const startTime = performance.now();

    function scrollAnimation(currentTime) {
        const elapsedTime = currentTime - startTime;
        const progress = Math.min(elapsedTime / duration, 1);
        const easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

        const easeProgress = easeInOutQuad(progress);
        const currentPosition = -scrollWidth * easeProgress + targetPosition; // Прокручиваем к целевой позиции
        scrollingItems.style.marginLeft = `${currentPosition}px`;

        if (progress < 1) {
            requestAnimationFrame(scrollAnimation);
        } else {
            // После завершения анимации, показываем выигрышный элемент
            showWinningItem(); // Показываем выигрышный элемент
            positionMarker(); // Позиционируем маркер над выигрышным элементом
        }
    }

    requestAnimationFrame(scrollAnimation);
}

function showWinningItem() {
    const winningItem = populatedItems[winningIndex]; // Получаем выигрышный предмет
    resultText.innerText = `Вы выиграли: ${winningItem.name}`;

    // Изменяем текст выигрышного предмета в scrollingItems
    const winningElement = scrollingItems.children[winningIndex];
    winningElement.classList.add("winning-item"); // Добавляем класс для стилей
    winningElement.innerText = winningItem.name; // Обновляем текст
}

function positionMarker() {
    // Ширина одного предмета
    const itemWidth = scrollingItems.children[0].offsetWidth; 
    // Центрируем маркер над выигрышным элементом
    const markerPosition = (winningIndex * itemWidth) - (caseContainer.offsetWidth / 2) + (itemWidth / 2); 
    // Устанавливаем позицию маркера
    marker.style.left = `${markerPosition}px`; 
}

openCaseButton.addEventListener("click", () => {
    // Очищаем текст результата
    resultText.innerText = ""; 
    // Очищаем массив предметов
    populatedItems = []; 
    // Очищаем элементы прокрутки
    scrollingItems.innerHTML = ""; 
    // Заполняем предметами при загрузке страницы
    populateItems(); 

    // Выбираем случайный индекс выигрышного предмета
    // Случайный индекс в пределах массива items
    winningIndex = Math.floor(Math.random() * populatedItems.length);
    // Запускаем анимацию прокрутки (уменьшено время)
    animateScroll(2000); 
});


И ее же добавляем в анимацию скролла.
Похожие вопросы