Правильное выпадение в рулетке

Есть рулетка, в неё передаются данные из колеса. Из этих данных рулетка выбирает случайный. Схема БД realtime firebase такая: схема БД

После нажатия кнопки крутится колесо, после остановки колеса должна начать крутиться рулетка с переданной редкостью. Рулетка крутится, но выпадает не то, на что показывает указатель (примерно на 2 карточки раньше как я понял). А ещё иногда рулетка вообще не крутится и стоит на месте, а после времени на кручение в консоль выводится то что она остановилась и т.п.

import { Wheel } from "react-custom-roulette";
import styles from "./DailyGift.module.css";
import { Link } from "react-router-dom";
import RoulettePro from "react-roulette-pro";
import "react-roulette-pro/dist/index.css";
import { database } from "../firebase";
import { ref, get } from "firebase/database";

const rarities = [
  { option: "Редкая", rarity: "Редкая", probability: 60 },
  { option: "Эпическая", rarity: "Эпическая", probability: 25 },
  { option: "Мифическая", rarity: "Мифическая", probability: 10 },
  { option: "Легендарная", rarity: "Легендарная", probability: 5 },
];

const rarityOptions = rarities.map((r) => ({ option: r.rarity }));

const weightedRarities = [];
rarities.forEach((r) => {
  for (let i = 0; i < r.probability; i++) {
    weightedRarities.push(r.rarity);
  }
});

export default function DailyGift() {
  const [mustSpin, setMustSpin] = useState(false);
  const [prizeNumber, setPrizeNumber] = useState(0);
  const [cars, setCars] = useState(rarityOptions);
  const [start, setStart] = useState(false);
  const [prizeIndex, setPrizeIndex] = useState(0);
  const [spinning, setSpinning] = useState(false);
  const [prizes, setPrizes] = useState([]);
  const [showCars, setShowCars] = useState(false);

  useEffect(() => {
    console.log("Prizes updated:", prizes);
  }, [prizes]);

  const getItemsByRarity = useCallback(async (rarity) => {
    const itemsRef = ref(database, "cars");
    try {
      const snapshot = await get(itemsRef);

      if (snapshot.exists()) {
        const itemsObject = snapshot.val();
        console.log("All fetched items:", itemsObject);

        const itemsArray = Object.keys(itemsObject).map((key) => ({
          id: key,
          ...itemsObject[key],
        }));

        const filteredItems = itemsArray.filter(
          (item) => item.rarityName === rarity
        );
        console.log(`Filtered items for rarity "${rarity}":`, filteredItems);

        return filteredItems;
      } else {
        console.log("No items found in database");
        return [];
      }
    } catch (error) {
      console.error("Error fetching data:", error);
      return [];
    }
  }, []);

  const getRandomItems = (items, count) => {
    const shuffled = items.sort(() => 0.5 - Math.random());
    return shuffled.slice(0, count);
  };

  const getRandomItemsByRarity = useCallback(
    async (rarity, count = 9) => {
      const items = await getItemsByRarity(rarity);
      if (items.length > 0) {
        return getRandomItems(items, count);
      } else {
        return [];
      }
    },
    [getItemsByRarity]
  );

  const generateId = () =>
    `${Date.now().toString(36)}+${Math.random().toString(36).substring(2)}`;

  const handleSpinClick = () => {
    if (!mustSpin) {
      setSpinning(true);
      const selectedRarity =
        weightedRarities[Math.floor(Math.random() * weightedRarities.length)];
      const newPrizeNumber = rarityOptions.findIndex(
        (r) => r.option === selectedRarity
      );
      setPrizeNumber(newPrizeNumber);
      setMustSpin(true);
      setShowCars(false); // До остановки колеса показываем вопросительные знаки
    }
  };

  const handleStopSpinning = async () => {
    setMustSpin(false);
    setSpinning(false); // Останавливаем вращение
    const selectedElement = cars[prizeNumber];
    console.log("Selected Element:", selectedElement);

    const randomItems = await getRandomItemsByRarity(selectedElement.option);
    console.log("Random Items:", randomItems);

    setPrizes(randomItems);
    console.log("Prizes:", randomItems); // Выводите рандомные призы
    setShowCars(true); // Показываем реальные призы
    setStart(true);
    setPrizeIndex(Math.floor(Math.random() * randomItems.length)); // Рандомный выбор индекса приза
  };

  const handlePrizeDefined = () => {
    setStart(false); // Останавливаем рулетку

    const selectedPrize = prizes[prizeIndex];
    console.log("? Prize defined! ?", selectedPrize);
    setShowCars(false); // Возвращаемся к вопросительным знакам после определения приза
  };

  const questionMarksObject = {
    logoUrl:
      "https://static.wikia.nocookie.net/6b13a411-b39d-4eaa-b1c2-d16c72439a3d",
  };

  const questionMarks = Array.from({ length: 9 }, () => ({
    ...questionMarksObject,
    id: generateId(),
  }));

  const prizesToDisplay = showCars ? prizes : questionMarks;

  const reproductionArray = (array = [], length = 0) => [
    ...Array(length)
      .fill("_")
      .map(() => array[Math.floor(Math.random() * array.length)]),
  ];

  const reproducedPrizeList = [
    ...prizesToDisplay,
    ...reproductionArray(prizesToDisplay, prizesToDisplay.length * 3),
    ...prizesToDisplay,
    ...reproductionArray(prizesToDisplay, prizesToDisplay.length),
  ];

  const prizeList = reproducedPrizeList.map((prize, index) => ({
    ...prize,
    id: `${generateId()}-${index}`, // Убедитесь, что каждый ID уникален
  }));

  return (
    <div className={styles.container}>
      <Link to={"/HomePage"} className={styles.LinkBack}>
        Назад
      </Link>
      <div className={styles.wheelContainer}>
        <Wheel
          mustStartSpinning={mustSpin}
          prizeNumber={prizeNumber}
          data={cars}
          onStopSpinning={handleStopSpinning}
          spinDuration={0.5}
        />
        <button
          onClick={handleSpinClick}
          className={styles.btnSPIN}
          style={{
            cursor: spinning ? "not-allowed" : "",
            backgroundColor: spinning ? "grey" : "",
          }}>
          {spinning ? "spinning..." : "spin"}
        </button>
      </div>
      <div className={styles.RoulProContainer}>
        <RoulettePro
          prizes={prizeList}
          prizeIndex={prizeIndex}
          start={start}
          spinningTime={6}
          onPrizeDefined={handlePrizeDefined}
          prizeItemRenderFunction={(prize) => (
            <div style={{ textAlign: "center" }} className={styles.card}>
              <img
                src={prize.logoUrl} // Используйте правильное поле
                alt="car logo"
                className={styles.carlogo}
              />
            </div>
          )}
        />
      </div>
    </div>
  );
}
  display: flex;
  flex-direction: row;
}

.wheelContainer {
  display: block;
  position: relative;
  width: 30%;
}

.RoulProContainer {
  width: 1250px;
  height: 170px;
  background-color: rgba(240, 248, 255, 0.301);
  backdrop-filter: blur(8px);
  padding: 20px 0 20px 0;
  border-radius: 10px;
}

.btnSPIN {
  position: absolute;
  left: 10px;
  background-color: rgb(87, 87, 185);
  border: transparent;
  height: 30px;
  width: 150px;
  border-radius: 5px;
  transition: ease-in-out 0.3s;
}

.btnSPIN:hover,
.btnSPINRpro:hover {
  background-color: rgb(76, 76, 114);
  cursor: pointer;
  transition: ease-in-out 0.3s;
}

.btnSPIN:active,
.btnSPINRpro:active {
  background-color: rgb(149, 149, 221);
  transition: ease-in-out 0.1s;
}

.btnSPINRpro {
  background-color: rgb(87, 87, 185);
  border: transparent;
  height: 30px;
  width: 150px;
  border-radius: 5px;
  transition: ease-in-out 0.3s;
}

.LinkBack {
  background-color: rgba(255, 255, 255, 0.39);
  backdrop-filter: blur(8px);
  border-radius: 5px;
  height: 20px;
  width: 60px;
  padding: 5px;
  text-decoration: none;
  color: black;
}

.card {
  position: relative;
  width: 150px;
  height: 150px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  transition: transform 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 5px;
}

.carlogo {
  width: 100px;
  height: auto;
  transition: transform 0.3s;
}

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