心血来潮写一个React的九宫格抽奖组件

 突然想写个react的九宫格抽奖组件,就浅尝一下。写个demo玩玩.

 0.5秒随机点亮奖项,按提供的奖品数组抽奖几率来决定最终中奖;

const items = [
  { id: 1, text: "谢谢惠顾", probability: 0.2 },
  { id: 2, text: "谢谢惠顾", probability: 0.2 },
  { id: 3, text: "谢谢惠顾", probability: 0.2 },
  { id: 4, text: "五等奖", probability: 0.15 },
  { id: 5, text: "四等奖", probability: 0.15 },
  { id: 6, text: "三等奖", probability: 0.09 },
  { id: 7, text: "二等奖", probability: 0.006 },
  { id: 8, text: "一等奖", probability: 0.003 },
  { id: 9, text: "特等奖", probability: 0.001 },
];
import React, { useState, useEffect } from "react";
import "./index.css";

const PrizeGrid = ({ items }) => {
  const [selected, setSelected] = useState(null);
  const [isRunning, setIsRunning] = useState(false);

  useEffect(() => {
    let timerId;
    if (isRunning) {
      timerId = setInterval(() => {
        const randomIndex = Math.floor(Math.random() * 9);
        console.log(randomIndex);
        setSelected(randomIndex);
      }, 500);
    }
    return () => clearTimeout(timerId);
  }, [isRunning, selected]);

  const handleClick = () => {
    if (isRunning) return;
    setIsRunning(true);
    setTimeout(() => {
      setIsRunning(false);
      const randomIndex = selectWinner(items);
      console.log("最后中奖", randomIndex);
      setSelected(randomIndex);
    }, 6000);
  };

  // 按奖品中奖几率抽奖逻辑  
  const selectWinner = (itemsArr) => {
    const probabilities = itemsArr.map((item) => item.probability);
    const sum = probabilities.reduce((acc, val) => acc + val, 0);
    const normalizedProbabilities = probabilities.map((p) => p / sum);

    let cumulativeProbability = 0;
    const cumulativeProbabilities = normalizedProbabilities.map((p) => {
      cumulativeProbability += p;
      return cumulativeProbability;
    });

    const randomNumber = Math.random();
    const selectedIndex = cumulativeProbabilities.findIndex(
      (cp) => randomNumber <= cp
    );

    return selectedIndex + 1;
  };

  return (
    <div className='prize-grid'>
      {items.map((item, index) => (
        <div
          key={item.id}
          className={`prize-grid-item ${
            selected === item.id ? "selected" : ""
          }`}
        >
          {item.text}
        </div>
      ))}
      <button className='prize-grid-button' onClick={handleClick}>
        {isRunning ? "Running..." : "Start"}
      </button>
    </div>
  );
};

export default PrizeGrid;

 index.css

.prize-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  margin: 20px;
  width: 300px;
  height: 300px;
}

.prize-grid-item {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  font-weight: bold;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #eee;
  color: #333;
  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3);
  transition: background-color 0.3s ease-in-out;
}

.prize-grid-item.selected {
  background-color: rgb(223, 113, 10);
}

.prize-grid-button {
  margin: 20px auto;
  display: block;
  padding: 10px;
  background-color: #00f;
  color: #fff;
  font-size: 16px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

还有其他的按照几率来随机中奖的工具方法,比如:

  1. 概率数组法:将所有奖品的概率存入一个数组中,然后生成一个随机数,根据随机数的值在概率数组中查找对应的奖品。

  2. 区间法:将所有奖品的概率转化为区间,然后生成一个0到1之间的随机数,在对应的区间内查找对应的奖品。

  3. 权重随机法:将所有奖品按照权重分配一个区间,然后生成一个随机数,根据随机数落在哪个区间来确定中奖的奖品。

这些方法都可以根据具体的需求来选择适合的方法。

  1. 概率数组法:
    function getRandomIndexByProbability(probabilityList) {
      const totalProbability = probabilityList.reduce((a, b) => a + b, 0); // 计算总概率
      let random = Math.random() * totalProbability; // 生成随机数
      for (let i = 0; i < probabilityList.length; i++) { // 循环概率数组
        random -= probabilityList[i]; // 减去当前奖品的概率
        if (random < 0) { // 判断是否中奖
          return i; // 返回中奖的奖品索引
        }
      }
    }
    
  2. 区间法:
    function getRandomIndexByInterval(intervalList) {
      const random = Math.random(); // 生成随机数
      let probability = 0;
      for (let i = 0; i < intervalList.length; i++) { // 循环区间数组
        if (random >= probability && random < intervalList[i]) { // 判断是否中奖
          return i; // 返回中奖的奖品索引
        }
        probability = intervalList[i]; // 记录上一个区间的概率
      }
    }
    

  3. 权重随机法:
    function getRandomIndexByWeight(weights) {
      const totalWeight = weights.reduce((a, b) => a + b, 0); // 计算总权重
      let random = Math.random() * totalWeight; // 生成随机数
      for (let i = 0; i < weights.length; i++) { // 循环权重数组
        random -= weights[i]; // 减去当前奖品的权重
        if (random < 0) { // 判断是否中奖
          return i; // 返回中奖的奖品索引
        }
      }
    }
    

点赞加关注哦!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
React九宫格抽奖是一种通过使用React框架来实现抽奖游戏。在这个游戏中,用户点击抽奖按钮后,九宫格开始旋转,并最终停在一个奖项上。 在实现这个功能的过程中,可以使用以下方法: 1. 首先,在点击抽奖按钮时,执行handleClick方法。这个方法会调用start方法来开始九宫格的旋转,并发起一个请求来获取奖项。 2. 在start方法中,首先设置九宫格的起始位置,结果序号和旋转速度。然后,使用定时器来控制九宫格的旋转。在每次定时器触发时,判断是否达到了预定的结果序号。如果没有达到,则继续旋转,并更新九宫格的活动位置。 3. 在每次旋转时,根据活动位置的变化,更新九宫格中奖项的激活状态,并将更新后的状态应用到界面上。 4. 当九宫格达到了预定的结果序号时,停止旋转,并展示中奖弹窗。 5. 可以使用setTimeout来延迟展示中奖弹窗的时间,并在展示完成后清除定时器。 通过以上步骤,就可以实现React九宫格抽奖游戏。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [react实现九宫格抽奖 - h5](https://blog.csdn.net/qq_16726735/article/details/121405662)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [React九宫格抽奖](https://blog.csdn.net/aoba8934/article/details/102322360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yusirxiaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值