Javascript - Spin the Wheel of Fortune

I am looking to create a wheel of fortune using JavaScript. My goal is to set both the output and starting position of the wheel. When the user spins the wheel at a minimum speed, it should rotate multiple times based on the speed before landing on the desired field.

Currently, I have only managed to implement the basic functionality. I am seeking assistance in completing the process as I am currently stuck.

How can I make the wheel rotate multiple times before stopping at the target angle?

let element = document.getElementById("wheel");
let region = new ZingTouch.Region(element);

let currentAngle = 0, 
targetAngle = 0; 
let minimumAngle = 30, 
rotatedAngle = 0, 
spinning = false

setInterval(() => {
  rotatedAngle = 0;
}, 200)

region.bind(element, 'rotate', function(e) {
  if (rotatedAngle > minimumAngle && rotatedAngle > 180) {
    spinning = true;
    document.getElementById("spinning").innerHTML = "spinning = true"
    // How can I make the wheel rotate multiple times ending with the target angle?
  } else if (!spinning) {
    currentAngle += e.detail.distanceFromLast;
    rotatedAngle += e.detail.distanceFromLast;
    element.style.transform = 'rotate(' + currentAngle + 'deg)';
  }
})
#wheel {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  width: 20%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/zingtouch/1.0.6/zingtouch.min.js"></script>
<img id="wheel" src="https://reel-mkt.com/templates/fortune_reel_lp/img/wheel.png">
<p id="spinning">spinning = false</p>

Answer №1

My approach to this task would be as follows:

  1. To initiate the spinning action, I would require an event such as "click"
  2. The calculation of the targetAngle involves generating a random angle:
    targetAngle = currentAngle + Math.random() * 360 + minimumAngle;
  3. For the animation, I am utilizing requestAnimationFrame.
  4. The speed is determined as 1/10 of the difference between the targetAngle and the currentAngle
  5. Contrary to the intended use of ZingTouch, I am not incorporating rotatedAngle into my solution.

I hope these steps align with your requirements.

let element = document.getElementById("wheel");
/*let region = new ZingTouch.Region(element);*/

let currentAngle = 0, // this is the current angle of the wheel by the rotate gesture
  targetAngle = 0; // blue field is the target where the wheel should stop
let minimumAngle = 30, // minimumAngle to make the wheel spinning
  //rotatedAngle = 0, // total spinned angle of the wheel by the rotate gesture
  spinning = false;

let rid = null;

element.addEventListener("click", () => {
  targetAngle = currentAngle + Math.random() * 360 + minimumAngle;

  if (spinning) {
    spinning = false;
     if (rid) {
      cancelAnimationFrame(rid);
      rid = null;
    }
  } else {   
    spinning = true;
    Animation();
  }
  
  is_spinning.innerHTML = spinning;
});

function Animation() {
  rid = requestAnimationFrame(Animation);
  if (currentAngle <= targetAngle) {
    let speed = (targetAngle - currentAngle)/10;
    currentAngle += speed;
    element.style.transform = `rotate(${currentAngle}deg)`;
        if(speed <= 1){// if the speed is < 1 stop the wheel
          cancelAnimationFrame(rid);
          spinning = false;
        }
    
  } else {//stop the wheel
    cancelAnimationFrame(rid);
    spinning = false;
  }
  
  is_spinning.innerHTML = spinning;
}
#wheel {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  width: 20%;
}
<img id="wheel" src="https://reel-mkt.com/templates/fortune_reel_lp/img/wheel.png">
<p>spinning = <span  id="is_spinning">false</span></p>

**One point to note**: The question is labeled under canvas, yet the image positioning in the code seems to suggest rotating the image instead of using canvas elements.

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

Displaying PDF Preview when Button is Clicked using Angular

Is there a way to preview a PDF using Base64 data? Here's the HTML code: And here's the TypeScript code: let file = new Blob([byte64String],{type:'application/pdf'}); this.pdfSourceUrl = URL.createObjectURL(file); When I try to prev ...

What is the best way to eliminate items from an array in a side-scrolling video game?

In my gaming project, I am creating a unique experience where the player needs to collect all the words from a given array. Currently, I am utilizing the shift() method to eliminate elements, as demonstrated in the code snippet below: if ( bX + bird.width ...

AngularJS: Establishing effective communication channels among directives

I am currently developing a custom directive for an audio player that supports mp3 files. The challenge I'm facing is how to handle multiple instances of the player on a single page. My goal is to ensure that when one player is active, starting anothe ...

What is the reason behind the addition of escape characters to the hidden input value?

<body> <div> <?= $_POST['msg'] ?> </div> <form id="frm" method="post"> <input type="hidden" name='msg' value='{"field0": "Im a string", "field1": 84, "field3": "so am I"}' /> < ...

Animate all shapes in SVG to rotate around a central pivot point

I am looking for a simple way to make an SVG graphic rotate around its center point. The rotation doesn't need to be smooth, just a 90 degree turn and back every second. https://i.sstatic.net/H6CTF.png Here is the SVG code: <?xml version="1.0" e ...

What is the reason for React's progressive bar displaying the complete percentage instead of progressively increasing it?

I am attempting to update the percentage state by adjusting setTimeout during the page load process, causing the filler to gradually fill the progressiveBar up to 100%. const { React, ReactDOM } = window const { useEffect, useState, Fragment } = React c ...

What is the best way to activate materialise pop-up menus in a React application?

Looking to enhance my React app by adding a NavBar with dropdown functionality. Here's the code snippet: <ul id="dropdown1" className="dropdown-content"> <li><NavLink to="/create">Create lesson ...

Tips for displaying personalized data with MUI DatePicker

I need to create a React TypeScript component that displays a MUI DatePicker. When a new date is selected, I want a custom component (called <Badge>) to appear in the value field. Previously, I was able to achieve this with MUI Select: return ( ...

Exploring the Difference Between Passing 0 and an Empty Array as the Second Argument in useEffect with React Hooks

Recently, I came across someone using 0 instead of an empty array for the second argument in useEffect. Instead of the typical: useEffect(() => { console.log('Run once'); }, []); they had: useEffect(() => { console.log('Run o ...

Why is my console showing a SyntaxError with JSON.parse and an unexpected character?

I am facing an issue. When I attempt to call a PHP page for some data with specific requested parameters using AJAX asynchronous call, I encounter the following error: SyntaxError: JSON.parse: unexpected character var jsonData = $.ajax({ u ...

Enhance the retrieval speed of MongoDB Altas queries for GET requests

Take a look at this snippet of code. exports.getTestCases = async (bucketName, startTimeStamp, endTimeStamp) => { let results = []; let startTime = parseInt(startTimeStamp); let endTime = parseInt(endTimeStamp); const maxDataLimit = 1500; cons ...

When transferring files using formData via axios, the server is unable to interpret the data

`` In my quest to figure out how to send a file from a client using an input type=file to an API, I came across the suggestion to use formData. Following some examples I found, I implemented this approach, but upon checking the data on the server side, it ...

Unresponsive Webpage

I am currently managing Facebook Ads for a client, but I have encountered an issue with their website not being responsive on mobile devices. While I have some knowledge of basic HTML & CSS, I am uncertain about how to address this particular problem. The ...

Fetching data from MongoDB, loading over 3000 entries and implementing pagination

I'm facing a challenge where I need to display more than 3000 results in an HTML table by fetching MachineID, Username, and Data from my MongoDB. However, I am encountering difficulties when trying to render this data using datatables. The MachineID ...

The Discord bot seems to be stuck on its old prefix and not updating

After changing the prefix from + to =, I am still facing issues with the old prefix. I have tried finding a solution by creating a new application, but the problem persists. Even after console logging, it only shows the new prefix. const Discord = requi ...

The dygraphs library is experiencing an issue due to a discrepancy between the number of labels and the number of

Having trouble with the dygraphs. I've extracted an array from PHP that appears like this: data = [ { "DATA": "2016-01-22", "TOTAL": [ "7", "4", "20", "0" ] }, { "DATA": "2016-01-25", "TOTAL": [ ...

Extract the arguments provided in the constructor invocation

Given const anInstance = new Plugin({ a: 'path' }) Is it possible to retrieve the arguments passed to the instance? anInstance./* some method */ === [{ a: 'path' }] // or someWrapper(anInstance) === [{ a: 'path' }] Const ...

ensure Selenium waits for animation to finish

I've encountered a problem regarding waiting for an animation to complete. Previously, I could rely on Selenium functions like wait.until(ExpectedConditions.... However, this is no longer sufficient. The element in question can be found in the HT ...

Can the content of a URL be preloaded before it is displayed?

My goal is to create a functionality where, upon clicking on a preview div, it expands to the screen size, displaying a custom loader, and then loads the content of a new URL when it's ready. Is this task achievable? const Works = ({changed}) => ...

What is the most efficient way to eliminate div elements from the DOM tree individually?

Check out this example. If you click the add button, a user card is added. You can remove all cards by clicking the "Clear" button. But how can you delete individual cards by clicking the "close" icon on each one? Here's the HTML code: <div clas ...