Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to draw a wheel of fortune?

Im trying to create a game of spin the wheel using this tutorial:

http://www.emanueleferonato.com/2015/07/31/create-a-wheel-of-fortune-for-your-html5-games-with-phaser-in-only-a-few-lines/

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.

like image 309
csbk Avatar asked Nov 22 '15 00:11

csbk


1 Answers

Wheel of fortune using JS Canvas

wheel of fortune game javascript

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>
like image 195
Roko C. Buljan Avatar answered Oct 12 '22 00:10

Roko C. Buljan