You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JavaScript实现带自定义概率权重的转盘抽奖功能

转盘自定义中奖概率实现方案

你现有代码的逻辑是随机生成旋转角度,再匹配对应奖项,因为每个扇区固定45度,所以各奖项概率均等。要实现自定义概率,推荐优先用「预抽奖项再反向匹配角度」的方案,不用修改现有转盘UI,兼容性最好。

具体实现方案

方案1:权重映射法(无需修改转盘UI)

先按自定义概率抽中目标奖项,再计算对应的旋转角度,让转盘最终刚好停在目标奖项的扇区范围内,视觉上和随机旋转效果完全一致。
改造后的完整代码如下:

(function() {
  const wheel = document.querySelector('.wheel');
  const startButton = document.querySelector('.button');
  const display = document.querySelector('.display');
  
  let deg = 0;
  const zoneSize = 45; // 现有转盘每个扇区固定45度,无需改动

  // 奖项配置
  const symbolSegments = {
    1: "Frog",
    2: "Snail",
    3: "Dolphin",
    4: "Ladybug",
    5: "Koala",
    6: "Unicorn",
    7: "Dragon",
    8: "Snowman",
  }
  // 自定义概率配置,总和需为100,可按需调整数值
  const prizeProbability = {
    1: 20, // 1号奖项20%
    2: 10, // 2号奖项10%
    3: 15, // 3号奖项15%
    4: 15, // 4号奖项15%
    5: 12, // 5号奖项12%
    6: 10, // 6号奖项10%
    7: 10, // 7号奖项10%
    8: 8   // 8号奖项8%
  }

  // 按权重抽取中奖奖项
  const getWinPrize = () => {
    const random = Math.random() * 100;
    let currentSum = 0;
    for (const prizeId in prizeProbability) {
      currentSum += prizeProbability[prizeId];
      if (random < currentSum) {
        return Number(prizeId);
      }
    }
    return 1; // 容错处理,默认返回1号奖项
  }

  const handleWin = (prizeId) => {
    display.innerHTML = symbolSegments[prizeId];
  }

  startButton.addEventListener('click', () => {
    startButton.style.pointerEvents = 'none';
    // 先确定中奖奖项
    const winPrize = getWinPrize();
    // 计算目标奖项对应角度区间的随机值,留2度余量避免卡在扇区分界线
    const minDeg = (winPrize - 1) * zoneSize + 2;
    const maxDeg = winPrize * zoneSize - 2;
    const targetActualDeg = Math.floor(minDeg + Math.random() * (maxDeg - minDeg));
    // 基础转15圈保证旋转效果自然,叠加目标角度得到最终旋转度数
    const baseDeg = 360 * 15;
    deg = baseDeg + targetActualDeg;
    
    wheel.style.transition = 'all 10s ease-out';
    wheel.style.transform = `rotate(${deg}deg)`;
    wheel.classList.add('blur');
  });

  wheel.addEventListener('transitionend', () => {
    wheel.classList.remove('blur');
    startButton.style.pointerEvents = 'auto';
    wheel.style.transition = 'none';
    const actualDeg = deg % 360;
    wheel.style.transform = `rotate(${actualDeg}deg)`;
    const winPrize = Math.ceil(actualDeg / zoneSize);
    handleWin(winPrize);
  });
})();

方案2:不等宽扇区适配法(需同步修改转盘UI)

如果需要转盘扇区的视觉宽度和中奖概率成正比,可以采用该方案:

  • 每个扇区的角度 = 360° * 对应奖项概率
  • 提前存储每个奖项对应的角度起始、结束区间
  • 抽中奖项后计算对应区间内的随机角度即可,核心逻辑和方案1一致,仅需将固定zoneSize改为动态计算的扇区角度。

内容的提问来源于stack exchange,提问作者Arun Bohra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:39:03