Im trying to create a game of spin the wheel using this tutorial:
however, this tutorial used an image for the wheel and i want to create it in html5/js. something vaguely like this:
https://www.winkbingo.com/images/lp/301114/spin_the_wheel_image.png this is what i have so far:
var ctx = canvas.getContext("2d");
var end = 0;
var color = ['#F0F8FF','#FAEBD7','#00FFFF','#7FFFD4','#00FF00','#FF8C00'];
var labels = ['label1', 'label2','label3','label4','label5','label6'];
var slices = 6
for (var i = 0; i < slices; i++) {
ctx.fillStyle = color[i];
ctx.beginPath();
ctx.moveTo(canvas.width/2,canvas.height/2);
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,end, ((1/slices)*Math.PI*2)+end ,false);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.fill();
end += ((1/slices)*Math.PI*2)+end;
}
i want the number of segments to be able to change by changing the variable slices(between 1-6). and i also want to display the labels on top. then i want to use this canvas instead of the image in that tutorial code so the wheel spins around with the text. hope that wasnt confusing. anyone know how to do this> i dont mind using any libraries etc.
const sectors = [ {color:"#f82", label:"Stack"}, {color:"#0bf", label:"10"}, {color:"#fb0", label:"200"}, {color:"#0fb", label:"50"}, {color:"#b0f", label:"100"}, {color:"#f0b", label:"5"}, {color:"#bf0", label:"500"}, ]; // Generate random float in range min-max: const rand = (m, M) => Math.random() * (M - m) + m; const tot = sectors.length; const elSpin = document.querySelector("#spin"); const ctx = document.querySelector("#wheel").getContext`2d`; const dia = ctx.canvas.width; const rad = dia / 2; const PI = Math.PI; const TAU = 2 * PI; const arc = TAU / sectors.length; const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard const angVelMin = 0.002; // Below that number will be treated as a stop let angVelMax = 0; // Random ang.vel. to acceletare to let angVel = 0; // Current angular velocity let ang = 0; // Angle rotation in radians let isSpinning = false; let isAccelerating = false; //* Get index of current sector */ const getIndex = () => Math.floor(tot - ang / TAU * tot) % tot; //* Draw sectors and prizes texts to canvas */ const drawSector = (sector, i) => { const ang = arc * i; ctx.save(); // COLOR ctx.beginPath(); ctx.fillStyle = sector.color; ctx.moveTo(rad, rad); ctx.arc(rad, rad, rad, ang, ang + arc); ctx.lineTo(rad, rad); ctx.fill(); // TEXT ctx.translate(rad, rad); ctx.rotate(ang + arc / 2); ctx.textAlign = "right"; ctx.fillStyle = "#fff"; ctx.font = "bold 30px sans-serif"; ctx.fillText(sector.label, rad - 10, 10); // ctx.restore(); }; //* CSS rotate CANVAS Element */ const rotate = () => { const sector = sectors[getIndex()]; ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`; elSpin.textContent = !angVel ? "SPIN" : sector.label; elSpin.style.background = sector.color; }; const frame = () => { if (!isSpinning) return; if (angVel >= angVelMax) isAccelerating = false; // Accelerate if (isAccelerating) { angVel ||= angVelMin; // Initial velocity kick angVel *= 1.06; // Accelerate } // Decelerate else { isAccelerating = false; angVel *= friction; // Decelerate by friction // SPIN END: if (angVel < angVelMin) { isSpinning = false; angVel = 0; } } ang += angVel; // Update angle ang %= TAU; // Normalize angle rotate(); // CSS rotate! }; const engine = () => { frame(); requestAnimationFrame(engine) }; elSpin.addEventListener("click", () => { if (isSpinning) return; isSpinning = true; isAccelerating = true; angVelMax = rand(0.25, 0.40); }); // INIT! sectors.forEach(drawSector); rotate(); // Initial rotation engine(); // Start engine!
#wheelOfFortune { display: inline-flex; position: relative; overflow: hidden; } #wheel { display: block; } #spin { font: 1.5rem/0 sans-serif; user-select: none; cursor: pointer; display: flex; justify-content: center; align-items: center; position: absolute; top: 50%; left: 50%; width: 30%; height: 30%; margin: -15%; background: #fff; color: #fff; box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6); border-radius: 50%; transition: 0.8s; } #spin::after { content: ""; position: absolute; top: -17px; border: 10px solid transparent; border-bottom-color: currentColor; border-top: none; }
<div id="wheelOfFortune"> <canvas id="wheel" width="300" height="300"></canvas> <div id="spin">SPIN asd asd asd as dasd as dasd asd asd as d</div> </div>
Just the plain canvas
of html5 has all that is needed to draw a quite good-looking "wheel of fortune" with very little code, no need for libraries.
arc
translate
/ rotate
global transformsFor example this is what I got with ~100 html lines (3.5k NOT minified) in total:
Live example at http://raksy.dyndns.org/wheel.html
I am the creator of a Javascript library called Winwheel.js which allows easy creation of winning/prize wheels on HTML canvas.
The wheels can be code drawn or use graphically rich images and it leverages Greensock's animation platform for the spinning and other animation effects.
Here is an example of how easy it is to create a basic code-drawn wheel using Winwheel.js...
var theWheel = new Winwheel({
'numSegments' : 8,
'segments' :
[
{'fillStyle' : '#eae56f', 'text' : 'Prize 1'},
{'fillStyle' : '#89f26e', 'text' : 'Prize 2'},
{'fillStyle' : '#7de6ef', 'text' : 'Prize 3'},
{'fillStyle' : '#e7706f', 'text' : 'Prize 4'},
{'fillStyle' : '#eae56f', 'text' : 'Prize 5'},
{'fillStyle' : '#89f26e', 'text' : 'Prize 6'},
{'fillStyle' : '#7de6ef', 'text' : 'Prize 7'},
{'fillStyle' : '#e7706f', 'text' : 'Prize 8'}
],
'animation' :
{
'type' : 'spinToStop',
'duration' : 5,
'spins' : 8
}
});
There is a full set of tutorials for Winwheel.js to help you get started on my site. If you are interested please visit http://dougtesting.net/
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.