React - The mechanics behind a spinning roulette wheel

I've been attempting to create a React roulette spinner but I've encountered some issues with the transitions and functionality.

Here is the initial version of the algorithm:
The callback functions are triggered whenever the 'winner' prop changes

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]);

To achieve this, I'm using a background image and mapping out each distance: https://i.sstatic.net/9a5vJ.png

The issue arises when the spinner sometimes fails to stop at the correct number and resizing the browser window causes it to malfunction. Are there any alternative ways to create a spinner or suggestions on how to improve the current implementation?

Answer №1

My initial idea was to create the spinner with a background to simplify the process rather than dealing with elements. However, I quickly realized that making it responsive was quite challenging using a background.

As a solution, I developed an algorithm that takes into account the width of the ticket and calculates the position based on the order and number of rows.

       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]);

By using this callback function, it ensures that the spinner will run every time there is a change in the winner prop.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a method in VBA to access elements generated by javascript code?

After spending several hours conducting thorough research on Google (including browsing StackOverflow), I've been trying to find a method that would allow me to target HTML elements generated by JavaScript in VBA. For instance, using ie.Document.getE ...

Angular encountering issues with loading external JavaScript files due to the error: ENOENT - indicating that the specified file or directory does

I am attempting to incorporate a bootstrap template into Angular. The template requires some external JavaScript and CSS files that need to be linked. I have placed these files in the assets folder and referenced them in the styles and scripts arrays of an ...

Improving Visibility in AngularJS

I am new to using Angular and encountering a simple issue. I have a button that, when clicked, should reveal a grid and some hidden filters. The filters are structured like this: <div ng-show="filtroFilial" style="visibility: hidden" class="col-md-2"&g ...

Is AngularJS causing issues with Foundation modals? Any solutions to this problem?

Wondering how to manage Foundation4 modals with AngularJS? I've noticed that when I navigate from a modal to a new view, the old modal disappears but the page stays darkened as if it's still there in the background. I tried adding a class attribu ...

Is it possible to send arguments to the functions executed by "jQuery then"?

Check out the complete code here: http://jsfiddle.net/BurFz/ http://jsbin.com/dagequha/1/edit?js,console /** * executed function chain */ func1('arg1').then(func2).then(func3).then(function () { console.log('execution comp ...

How to transform a hyperlink into a clickable element within an absolutely positioned container

I'm currently working on a photo gallery project and using magnific popup to create it. However, I ran into an issue with the hover event on the images that displays an icon when it's hovered over, indicating that it can be clicked to view more. ...

Searching for data in Express JS with MongoDB using the $or operator is not possible

I am currently developing an API for managing my invoice data. Within this data, there are boolean values that determine the status of the invoices. For example, some invoices are marked as 'payment received', and I need to search for those speci ...

Generating Speech from Text using jQuery API in HTML

Can a website be created to detect textbox text upon longClick by the user, and function across various browsers? The site should also have mobile compatibility. Appreciate any help! ...

Can you explain the purpose of the spaces on the buttons?

mysterious button spacing issue <div class="buttons"> <button id="btn-search" type="submit">Search Engine</button> <button id="btn-lucky" type="submit">Feeling Lucky Today</button> </div> .buttons { max-width: 29 ...

AJAX does not execute all inline JavaScript code

I am currently using AJAX to load a fragment of a document. I have successfully loaded 'external' scripts, but I am encountering issues when trying to execute all the JavaScript within <script> tags. Below is an example of the HTML fragmen ...

How to troubleshoot Props not functioning in nextjs-typescript?

I'm having trouble with props in my project and I can't seem to figure it out! Here are the three files. I'm still learning typescript but everything seems fine in the code, yet it's not working! Here is index.tsx file: const Home: ...

Developing mobile applications using React Native

An error occurred while trying to install the app. Please ensure that your Android development environment is configured correctly. You can set it up by following the instructions at: https://reactnative.dev/docs/environment-setup. Run the CLI with the -- ...

How can you effectively use a table filter extension to sort through dropdown values?

Is there a way to update the dropdown values based on new data after applying the first filter? For example, only displaying $0 in the second dropdown menu? Essentially, I want to filter the values in a table and then have the dropdown options reflect the ...

Turn off drag and drop functionality and activate selection in HTML

Recently, I encountered a strange issue where selected text became draggable and droppable onto other text, causing it to concatenate. To resolve this problem, I added the following code: ondragstart="return false" onmousedown="return false" However, thi ...

Having trouble with the `npm start` command while working with react.js?

Currently, I am in the process of setting up React.js. To achieve this, I executed npm install -g create-react-app followed by create-react-app my-app. Afterward, I proceeded to run the npm start command but encountered the error displayed below. https:// ...

Expanding the StringConstructor in TypeScript results in a function that is not defined

I'm currently trying to enhance the String class in TypeScript 2.5 by adding a static method, which will be compiled to ES5. Here's what I have in StringExtensions.d.ts: declare interface StringConstructor { isNullOrEmpty(value: string | nu ...

Tips for getting rid of the glowing effect on MUI slider thumbs when they are in focus

import * as React from "react"; import Box from "@mui/material/Box"; import Slider from "@mui/material/Slider"; function valuetext(value) { return `${value}°C`; } export default function RangeSlider() { const [value, se ...

Tips on configuring a hidden input field to validate a form

I am currently attempting to create a blind input field using PHP that will validate if the input field is empty. If it's not empty, the message set up to be sent will not send. However, I have encountered several issues with the placement and wording ...

Adding text with jQuery

Currently, I am utilizing the Jquery text editor plugin known as JqueryTE. While adding some functions to it, I have encountered a roadblock. Specifically, I am attempting to insert additional text into the source of the textarea but have been unsuccessfu ...

Nashorn poses a security threat due to its ClassFilter vulnerability

Encountering some troubles with Nashorn and came across a concerning security vulnerability highlighted here: It appears that someone can easily execute code using this command: this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().ex ...