简体   繁体   中英

Spinning a wheel of fortune with a predetermined rotation value

My goal is to (upon clicking a button) spin a wheel multiple times, then end on a specific rotation value (0...360) while easing out the animation. I can currently 'smoothly' spin to a specific point on the wheel without any full revolutions. My problem is trying to spin the wheel multiple times and then landing on a specific point to make it look more realistic. Is this achievable with the CSS animaton property or anything else?

Here is my code...

 const wheelEl = document.getElementById("wheel"); const sliceSize = 360 / 3; function spinWheel(index) { // Reset animation wheelEl.style.transition = "none"; wheelEl.style.transform = "rotate(0deg)"; // Play animation on the next frame setTimeout(() => { wheelEl.style.transition = "all ease 1s"; // Target rotation margin let rotMin = (sliceSize * (index))+(sliceSize/15); let rotMax = (sliceSize * (index + 1))-(sliceSize/15); // Target rotation let rot = Math.floor(Math.random() * (rotMax - rotMin + 1) + rotMin); wheelEl.style.transform = `rotate(-${rot}deg)`; }, 0); }
 #container { position: absolute; text-align: center; } #arrow { position: absolute; top: -5px; left: 50%; transform: translateX(-50%); border-top: 10px solid black; border-left: 8px solid transparent; border-right: 8px solid transparent; z-index: 1; } #wheel { width: 100px; height: 100px; border-radius: 50%; background-image: conic-gradient(lightpink 0 120deg, lightblue 0 240deg, lightsalmon 0 360deg); }
 <div id="container"> <div id="arrow"></div> <div id="wheel"></div> <br /> <button onclick="spinWheel(2)">Spin wheel</button> </div>

You can stick to using transform.

This snippet does two things: adds a random (within bounds) number of 360 degrees to the rotation value and sets the easing function to ease-out so that the rotation slows down towards the end only.

So that the effect can be seen, the time of the full rotation is set to 5 seconds but of course alter this to whatever you want. You could for example make that random within some bounds too if desired.

You could also play with the Beziere function that represents ease-out if say you wanted a longer stretch of it seeming to slow down.

 const wheelEl = document.getElementById("wheel"); const sliceSize = 360 / 3; function spinWheel(index) { // Reset animation wheelEl.style.transition = "none"; wheelEl.style.transform = "rotate(0deg)"; // Play animation on the next frame setTimeout(() => { wheelEl.style.transition = "all ease-out 5s"; // Target rotation margin const rotMin = (sliceSize * (index)) + (sliceSize / 15); const rotMax = (sliceSize * (index + 1)) - (sliceSize / 15); // Target rotation const fullRots = Math.floor(Math.random() * 5) + 5; // minimum 5 rotations max 9 const rot = (fullRots * 360) + Math.floor(Math.random() * (rotMax - rotMin + 1) + rotMin); wheelEl.style.transform = `rotate(-${rot}deg)`; }, 0); }
 #container { position: absolute; text-align: center; } #arrow { position: absolute; top: -5px; left: 50%; transform: translateX(-50%); border-top: 10px solid black; border-left: 8px solid transparent; border-right: 8px solid transparent; z-index: 1; } #wheel { width: 100px; height: 100px; border-radius: 50%; background-image: conic-gradient(lightpink 0 120deg, lightblue 0 240deg, lightsalmon 0 360deg); }
 <div id="container"> <div id="arrow"></div> <div id="wheel"></div> <br /> <button onclick="spinWheel(2)">Spin wheel</button> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM