首页 > 解决方案 > React - 轮盘赌旋转器的算法

问题描述

我一直在尝试用 React 制作轮盘赌旋转器。但我正在处理一些与转换和角色相关的问题。

这是该算法的第一个版本:
回调函数在每次名为获胜者的道具发生变化时运行

const slideRef = useRef(null);
function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}
const spinnerAnimation = useCallback(() => {
  const numbers = {
    0: 560,
    11: -410,
    5: 160,
    10: 320,
    6: 480,
    9: 720,
    7: 880,
    8: 1050,
    1: 1135,
    14: 960,
    2: 800,
    13: 640,
    3: 400,
    12: 240,
    4: 80,
  };
  const cycles = Math.floor(getRandomArbitrary(2, 4));
  const dev = getRandomArbitrary(0, 80);
  const scrollAmount = 480 + numbers[winner] + dev + 1200 * cycles;
  slideRef.current.classList.remove('spin_animation');
  slideRef.current.style = 'background-position-x: -212.5px';
  setTimeout(() => {
    slideRef.current.classList.add('spin_animation');
    slideRef.current.style = `background-position-x: ${`-${scrollAmount}px
  }, 10);
}, [winner]);

为此,我使用背景并映射每个距离: 在此处输入图像描述

我的问题是,有时它不会停在正确的数字上,而且当我们调整浏览器窗口的大小时它也会中断。有没有其他方法可以制作微调器,或者我该如何改进?

标签: javascriptcssreactjsfrontend

解决方案


我认为使用背景制作微调器比处理元素更容易。但是有了背景,很难让它做出响应。

所以我做了一个算法,它采用票的宽度并根据订单和行数计算位置。

       const spinWheel = useCallback(() => {
    // Receives the winner prop and search for his position in the spinner be
    const order = [8, 1, 14, 2, 13, 3, 12, 4, 0, 11, 5, 10, 6, 9, 7];
    const position = order.indexOf(winner);

    // Determine position where to land
    const rows = 12;
    const card = 80 + 2 * 2;
    let landingPosition = rows * 15 * card + position * card;

    const randomize = Math.floor(Math.random() * 75) - 75 / 2;
    landingPosition += randomize;

    const axes = {
      x: Math.floor(Math.random() * 50) / 100,
      y: Math.floor(Math.random() * 20) / 100,
    };

    // Set animations and spinner translation
    wheelRef.current.style.transitionTimingFunction = `all 6000ms cubic-bezie
    wheelRef.current.style.transitionDuration = `6s`;
    wheelRef.current.style.transform = `translate3d(-${landingPosition}px, 0p

    // Reset animations and translation to init a new round
    setTimeout(() => {
      wheelRef.current.style.transitionTimingFunction = '';
      wheelRef.current.style.transitionDuration = '';
      const resetTo = -(position * card + randomize);
      wheelRef.current.style.transform = `translate3d(${resetTo}px, 0px, 0px)
    }, 7000);
  }, [winner]);

由于它是一个回调,因此该函数将在获胜者道具的每次更改时运行。


推荐阅读