I have some html5 and javascript code to create a spinning roulette wheel. It is split up into 14 outcomes. My question is, how can I get some unique HTML code to display per each outcome of the wheel. For example, if the wheel lands on Business, some text will appear below the wheel that has information on Business.
Here is my HTML code and below it is a link to a working example:
<!--[if IE]><script type="text/javascript" src="/sites/default/files/1010/source/excanvas.js"></script><![endif]-->
<input type="button" value="spin" onclick="spin();" style="float: left;" />
<canvas id="wheelcanvas" width="800" height="750"></canvas>
<script type="application/javascript">
var colors = ["#B8D430", "#3AB745", "#029990", "#3501CB",
"#2E2C75", "#673A7E", "#CC0071", "#F80120",
"#F35B20", "#FB9A00", "#FFCC00", "#FEF200", "#B2DF00", "#5C8300"];
var classes = ["Business", "Office Education", "Continuing Care Assistant", "Practical Nursing",
"Primary Care Paramedic", "Early Childhood Education", "Cooking", "Electrician",
"Heavy Equipment Operator", "Industrial Mechanic - Millwright", "Plumbing & Pipefitting", "Truck Driver Training", "Welding", "Power Engineering"];
var startAngle = 0;
var arc = Math.PI / 7;
var spinTimeout = null;
var spinArcStart = 10;
var spinTime = 0;
var spinTimeTotal = 0;
var ctx;
function draw() {
drawRouletteWheel();
}
function drawRouletteWheel() {
var canvas = document.getElementById("wheelcanvas");
if (canvas.getContext) {
var outsideRadius = 300;
var textRadius = 260;
var insideRadius = 100;
ctx = canvas.getContext("2d");
ctx.clearRect(5,0,1000,1000);
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.font = 'bold 10px sans-serif';
for(var i = 0; i < 14; i++) {
var angle = startAngle + i * arc;
ctx.fillStyle = colors[i];
ctx.beginPath();
ctx.arc(400, 400, outsideRadius, angle, angle + arc, false);
ctx.arc(400, 400, insideRadius, angle + arc, angle, true);
ctx.stroke();
ctx.fill();
ctx.save();
ctx.shadowOffsetX = -1;
ctx.shadowOffsetY = -1;
ctx.shadowBlur = 0;
ctx.shadowColor = "rgb(220,220,220)";
ctx.fillStyle = "black";
ctx.translate(400 + Math.cos(angle + arc / 2) * textRadius, 400 + Math.sin(angle + arc / 2) * textRadius);
ctx.rotate(angle + arc / 2 + Math.PI / 2);
var text = classes[i];
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
}
//Arrow
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(400 - 4, 400 - (outsideRadius + 5));
ctx.lineTo(400 + 4, 400 - (outsideRadius + 5));
ctx.lineTo(400 + 4, 400 - (outsideRadius - 5));
ctx.lineTo(400 + 9, 400 - (outsideRadius - 5));
ctx.lineTo(400 + 0, 400 - (outsideRadius - 13));
ctx.lineTo(400 - 9, 400 - (outsideRadius - 5));
ctx.lineTo(400 - 4, 400 - (outsideRadius - 5));
ctx.lineTo(400 - 4, 400 - (outsideRadius + 5));
ctx.fill();
}
}
function spin() {
spinAngleStart = Math.random() * 10 + 10;
spinTime = 0;
spinTimeTotal = Math.random() * 3 + 4 * 1000;
rotateWheel();
}
function rotateWheel() {
spinTime += 30;
if(spinTime >= spinTimeTotal) {
stopRotateWheel();
return;
}
var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
startAngle += (spinAngle * Math.PI / 180);
drawRouletteWheel();
spinTimeout = setTimeout('rotateWheel()', 30);
}
function stopRotateWheel() {
clearTimeout(spinTimeout);
var degrees = startAngle * 180 / Math.PI + 90;
var arcd = arc * 180 / Math.PI;
var index = Math.floor((360 - degrees % 360) / arcd);
ctx.save();
ctx.font = 'bold 30px sans-serif';
var text = classes[index]
ctx.fillText(text, 400 - ctx.measureText(text).width / 2, 400 + 10);
ctx.restore();
document.getElementById('wheelResult').innerHTML = 'Test' + text;
}
function easeOut(t, b, c, d) {
var ts = (t/=d)*t;
var tc = ts*t;
return b+c*(tc + -3*ts + 3*t);
}
draw();
</script>
<p id="wheelResult"></p>
http://www.ctrc.sk.ca/wheel.html
There are a couple of ways to do it but this is the way I would do it.
You could create a div tag with the css style of display:none and then set it with the info desired and hide and show it as needed.
Example:
<script>
var htmlData = ['<h1>Business</h1><br><span>What is Business?</span><br>...', ...];
....
function spin()
{
//Hide description box.
document.getElementById('idDescriptionBox').style.display = 'none';
spinAngleStart = Math.random() * 10 + 10;
....
}
....
function stopRotateWheel()
{
....
//Set description and display it.
var descriptionBox = document.getElementById('idDescriptionBox');
descriptionBox.innerHTML = htmlData[index];
descriptionBox.style.display = 'block';
}
....
</script>
<div id="idDescriptionBox" style="display:none;">
<!--Description info in here-->
....
</div>
Related
I am developing a game in ionic 4 'spin the wheel'. so far I am able to spin the wheel which stops randomly on any of the sections. Can anyone help me with setting probability to sections so that users will have fewer chances to win? I would like to pre-define each section with some percentage value. for eg section with 0 will have 50% 4 will have 10% etc, and the greatest value will have a 1% chance to win. below code, I have tried.
SpinWheel.ts
export class SpinWheel {
#ViewChild('myCanvas', { static: false }) myCanvas: ElementRef;
colors = ["#2a8251", "#dc0927", "#414243", "#dc0927", "#2E2C75",
"#dc0927", "#414243", "#dc0927", "#2E2C75",
"#dc0927"];
restaraunts = ["0", "32", "15", "19",
"4", "21", "2", "25",
"17", "34"];
startAngle = 0;
arc = 2 * Math.PI / 10;
spinTimeout = null;
spinArcStart = 10;
spinTime = 0;
spinTimeTotal = 0;
ctx;
spinAngleStart;
constructor() {
}
ngOnInit() {
}
ngAfterViewInit(): void {
this.draw();
}
draw() {
this.drawRouletteWheel();
}
drawRouletteWheel() {
var canvas = document.getElementById("wheelcanvas");
var outsideRadius = 140;
var textRadius = 120;
var insideRadius = 25;
this.ctx = (<HTMLCanvasElement>this.myCanvas.nativeElement).getContext('2d');
this.ctx.clearRect(0, 0, 500, 500);
this.ctx.strokeStyle = "black";
this.ctx.lineWidth = 2;
this.ctx.font = 'bold 12px sans-serif';
for (var i = 0; i < 10; i++) {
var angle = this.startAngle + i * this.arc;
this.ctx.fillStyle = this.colors[i];
this.ctx.beginPath();
this.ctx.arc(150, 150, outsideRadius, angle, angle + this.arc, false);
this.ctx.arc(150, 150, insideRadius, angle + this.arc, angle, true);
this.ctx.stroke();
this.ctx.fill();
this.ctx.save();
this.ctx.shadowOffsetX = -1;
this.ctx.shadowOffsetY = -1;
this.ctx.shadowBlur = 0;
//this.ctx.shadowColor = "rgb(220,220,220)";
this.ctx.fillStyle = "white";
this.ctx.translate(150 + Math.cos(angle + this.arc / 2) * textRadius, 150 + Math.sin(angle + this.arc / 2) * textRadius);
this.ctx.rotate(angle + this.arc / 2 + Math.PI / 2);
var text = this.restaraunts[i];
this.ctx.fillText(text, -this.ctx.measureText(text).width / 2, 0);
this.ctx.restore();
}
//Arrow
this.ctx.fillStyle = "black";
this.ctx.beginPath();
this.ctx.moveTo(150 - 4, 150 - (outsideRadius + 5));
this.ctx.lineTo(150 + 4, 150 - (outsideRadius + 5));
this.ctx.lineTo(150 + 4, 150 - (outsideRadius - 5));
this.ctx.lineTo(150 + 9, 150 - (outsideRadius - 5));
this.ctx.lineTo(150 + 0, 150 - (outsideRadius - 13));
this.ctx.lineTo(150 - 9, 150 - (outsideRadius - 5));
this.ctx.lineTo(150 - 4, 150 - (outsideRadius - 5));
this.ctx.lineTo(150 - 4, 150 - (outsideRadius + 5));
this.ctx.fill();
}
spin() {
this.spinAngleStart = Math.random() * 10 + 10;
this.spinTime = 0;
this.spinTimeTotal = Math.random() * 3 + 4 * 1000;
this.rotateWheel();
}
rotateWheel() {
this.spinTime += 30;
if (this.spinTime >= this.spinTimeTotal) {
this.stopRotateWheel();
return;
}
var spinAngle = this.spinAngleStart - this.easeOut(this.spinTime, 0, this.spinAngleStart, this.spinTimeTotal);
this.startAngle += (spinAngle * Math.PI / 180);
this.drawRouletteWheel();
this.spinTimeout = setTimeout(() => {
this.rotateWheel();
}, 30);
}
stopRotateWheel() {
clearTimeout(this.spinTimeout);
var degrees = this.startAngle * 180 / Math.PI + 90;
var arcd = this.arc * 180 / Math.PI;
var index = Math.floor((360 - degrees % 360) / arcd);
this.ctx.save();
this.ctx.font = 'bold 30px sans-serif';
var text = this.restaraunts[index]
//this.ctx.fillText(text, 150 - this.ctx.measureText(text).width / 2, 150 + 10);
alert("You got:\n" + text);
this.ctx.restore();
}
// t: current time
// b: start value
// c: change in value
// d: duration
easeOut(t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b;
}
}
spin_wheel.html
<div class="wheel">
<canvas #myCanvas width="auto" height="300"></canvas>
<div class="icon-center"><img class="app-logo" (click)="spin()" src="../../assets/icon/favicon.png"/></div>
</div>
See attached image spin wheel screen
Thanks in advance.
I have two circles rotating round the circle and I would like the circle to change the speed at random after passing one revolution.Both circle should be at different speed or they might be the same speed (then collision will occurs). For example, during first run, both circles are moving at 10m/s and after it reaches end of the revolution,they will collide.Let's say after the revolution, it changes circle 1 to 15m/s and circle 2 to 30m/s , then they won't collide.I would like to know how to achieve this. This is just an idea of what i am trying to achieve. It would be even better if the speed is randomized after every revolution.
Any help would be appreciated.
Code:
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
draw2();
setTimeout(function() {
draw()
}, 30);
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
draw();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
What you can do is to declare a local speed variable to the draw() function, then pass it to the setTimeout() callback, like this:
var speed = Math.floor(Math.random() * 11);
draw2();
setTimeout(function() {
draw()
}, speed);
The code Math.floor(Math.random() * 11) will give you a random number between 0 and 10 so setTimeout will be called with a different speed each time.
Demo:
window.onload = function() {
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
var speed = Math.floor(Math.random() * 11);
draw2();
setTimeout(function() {
draw()
}, speed);
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
draw();
})();
}
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
You can change the timeGap when angle becomes 360, i.e., when a revolution completes. Thus, it will appear as the speed is getting changed.
Inside your draw() function:
if(angle % 360 == 0) {
timeGap = Math.random() * 20 + 5;
}
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20,
angle1 = 0,
angle2 = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0,
timeGap1 = 10,
timeGap2 = 10,
diff = 20,
minTimeGap = 20;
function draw() {
velX = Math.cos(angle1 * Math.PI / 180) * thrust;
velY = Math.sin(angle1 * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle1 += 2;
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
if(angle1 % 360 == 0) {
timeGap1 = Math.random() * diff + minTimeGap;
}
setTimeout(function() {
draw();
}, timeGap1);
}
function draw2() {
velX = Math.cos(angle2 * Math.PI / 180) * thrust;
velY = Math.sin(angle2 * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle2 += 2;
ctx.fillStyle = "#007700";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
if(angle2 % 360 == 0) {
timeGap2 = Math.random() * diff + minTimeGap;
}
setTimeout(function() {
draw2();
}, timeGap2);
}
function clearCanvas() {
ctx.fillStyle = 'rgba(220,220,220,0.5)';
ctx.fillRect(0, 0, 550, 400);
collisiondetection();
setTimeout(function() {
clearCanvas();
}, timeGap2 + timeGap1);
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter + "<br/>Speed1: " + timeGap1 + "<br/>Speed2: " + timeGap2;
collide = true;
}
} else {
collide = false;
}
}
draw();
draw2();
clearCanvas();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0,
maxSpeed = 100,
speed = Math.floor(Math.random() * 100) + 1;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
draw2();
SpeedCount();
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
function SpeedCount(){
(function(speed) {
setTimeout(function() {
draw()
}, speed);
})(speed);
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
if((angle + 90) % 360 == 0){
speed = Math.floor(Math.random() * maxSpeed) + 1;
}
}
draw();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
try this one.
Let's rework it a bit:
First, when programming a graphical animation, you should separate your objects logic and your drawing operations.
The drawing operations should occur at regular intervals, based on the screen refresh rate (to avoid drawing sometimes twice a frame and sometimes not drawing at all).
A convenient method available in the Web API for this exact case is requestAnimationFrame(callback). It will queue our callback to fire just before the next screen refresh rate.
So we can use it as the core of our animation loop, that will always fire at the same rate as our screen can show (usually 60FPS).
When you have animated objects on your scene, the simplest data-structure in js, are Objects. Instead of holding a lot of variables everywhere, you pack them in their own object.
When you have multiple such objects, you hold them all together (e.g in an Array).
Now, in our animation loop, we will first update our objects position, then draw them.
It is in the update part that we will control the velocity of our objects, and only after we did update all the object, we will check if they collide.
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
max_speed = Math.PI / 12,
objects = [{
center_x: 160,
center_y: 120,
speed: Math.random() % max_speed,
angle: 0,
color: '#000'
},
{
center_x: 330,
center_y: 280,
speed: -(Math.random() % max_speed),
angle: 0,
color: "#80ced6"
}
],
radius = 20,
outerRad = 120,
totalcounter = 0,
collide = true;
anim(); // begin our main anim loop
function anim() {
update(); // our objects update logic
draw(); // now we draw
collisiondetection(); // DOM update
requestAnimationFrame(anim); // start again #next-frame
}
function update() {
// here we only change the object's properties
// nothing graphical should come here
objects.forEach(function(object) {
var angle = object.angle;
object.x = Math.cos(angle) * outerRad + object.center_x;
object.y = Math.sin(angle) * outerRad + object.center_y;
object.angle += object.speed;
});
}
function draw() {
// here is only the graphical part
// no logic should come here
ctx.clearRect(0, 0, 550, 400);
objects.forEach(function(object) {
ctx.fillStyle = object.color;
ctx.beginPath();
ctx.arc(object.x, object.y, radius, 0, Math.PI * 2);
ctx.fill();
});
}
function collisiondetection() {
var o1 = objects[0],
o2 = objects[1];
var distance = Math.sqrt((o1.x - o2.x) * (o1.x - o2.x) + (o1.y - o2.y) * (o1.y - o2.y));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
// and now if you want to update randomly these object's speed, you can do from anywhere
document.onclick = function() {
objects[0].speed = Math.random() % max_speed;
objects[1].speed = -(Math.random() % max_speed);
};
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<p id="cTotal">Total collisions: </p>
I found this js spinner and I like how it has the counter at the end. It counts down from 15 seconds. I was wondering if it would be possible to make it so that if you land on geography for example it counts down 5 seconds and then redirects you to a separate website. And history would bring you to a different link and so on. Thanks
JavaScript
var colors = ["#ffff00" , "#1be11b", "#0000ff", "#7e7e7e", "#8a2be2", "#006400", "#2980B9", "#E74C3C"];
// NEED to pre load this data prior
var prize_descriptions = ["GENERAL", "GEOGRAPHY", "HISTORY", "ARTS", "SCIENCE", "SPORTS", "RELIGION", "MEDIA"];
var current_user_status = {};
var startAngle = 0;
var arc = Math.PI / 4;
var spinTimeout = null;
var spinArcStart = 10;
var spinTime = 0;
var spinTimeTotal = 0;
var current_user_status = null;
var spin_results = null;
var wheel;
var counter, tt;
function drawSpinnerWheel() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var outsideRadius = 200;
var textRadius = 160;
var insideRadius = 125;
wheel = canvas.getContext("2d");
wheel.clearRect(0, 0, 500, 500);
wheel.strokeStyle = "#ecf0f1";
wheel.lineWidth = 5;
wheel.font = '12px Helvetica, Arial';
for (var i = 0; i < 8; i++) {
var angle = startAngle + i * arc;
wheel.fillStyle = colors[i];
wheel.beginPath();
wheel.arc(250, 250, outsideRadius, angle, angle + arc, false);
wheel.arc(250, 250, insideRadius, angle + arc, angle, true);
wheel.stroke();
wheel.fill();
wheel.save();
wheel.shadowOffsetX = -1;
wheel.shadowOffsetY = -1;
wheel.shadowBlur = 0;
wheel.shadowColor = "rgb(220,220,220)";
wheel.fillStyle = "#ecf0f1";
wheel.translate(250 + Math.cos(angle + arc / 2) * textRadius, 250 + Math.sin(angle + arc / 2) * textRadius);
wheel.rotate(angle + arc / 2 + Math.PI / 2);
var text = prize_descriptions[i];
if (text === undefined) text = "Not this time!";
wheel.fillText(text, -wheel.measureText(text).width / 2, 0);
wheel.restore();
}
//Arrow
wheel.fillStyle = "#ecf0f1";
wheel.beginPath();
wheel.moveTo(250 - 4, 250 - (outsideRadius + 5));
wheel.lineTo(250 + 4, 250 - (outsideRadius + 5));
wheel.lineTo(250 + 4, 250 - (outsideRadius - 5));
wheel.lineTo(250 + 9, 250 - (outsideRadius - 5));
wheel.lineTo(250 + 0, 250 - (outsideRadius - 13));
wheel.lineTo(250 - 9, 250 - (outsideRadius - 5));
wheel.lineTo(250 - 4, 250 - (outsideRadius - 5));
wheel.lineTo(250 - 4, 250 - (outsideRadius + 5));
wheel.fill();
}
}
function spin() {
$("#spin").unbind('click');
$("#spin").attr("id", "nospin");
document.getElementById('timer').innerHTML = " ";
document.getElementById('category').innerHTML = " ";
spinMovement = Math.floor(Math.random() * 20) + prize_descriptions.length * 2;
spinAngleStart = 1 * 10 + spinMovement;
spinTime = 0;
spinTimeTotal = Math.floor(Math.random() * 4) * Math.floor(Math.random() * 6) + Math.floor(Math.random() * 8) * Math.floor(Math.random() * 2000) + 2000;
console.log(spinMovement + " - " + spinTimeTotal);
rotateWheel();
}
function rotateWheel() {
spinTime += 30;
if (spinTime >= spinTimeTotal) {
stopRotateWheel();
return;
}
var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
startAngle += (spinAngle * Math.PI / 180);
drawSpinnerWheel();
spinTimeout = setTimeout('rotateWheel()', 30);
}
function stopRotateWheel() {
clearTimeout(spinTimeout);
var degrees = startAngle * 180 / Math.PI + 90;
var arcd = arc * 180 / Math.PI;
var index = Math.floor((360 - degrees % 360) / arcd);
wheel.save();
wheel.font = '30px "Homestead-Inline", Helvetica, Arial';
var text = prize_descriptions[index];
//wheel.fillText(text, 250 - wheel.measureText(text).width / 2, 250 + 10);
wheel.restore();
document.getElementById('timer').innerHTML = "15";
document.getElementById('category').innerHTML = "Your Category is: " + text;
counter = 15;
tt=setInterval(function(){startTime()},1000);
}
function easeOut(t, b, c, d) {
var ts = (t /= d) * t;
var tc = ts * t;
return b + c * (tc + -3 * ts + 3 * t);
}
drawSpinnerWheel();
function startTime() {
if(counter == 0) {
clearInterval(tt);
$("#nospin").attr("id", "spin");
$("#spin").bind('click', function(e) {
e.preventDefault();
spin();
});
} else {
counter--;
}
document.getElementById('timer').innerHTML = counter;
}
$("#spin").bind('click', function(e) {
e.preventDefault();
spin();
});
To see it in action click here
It seems that all your changes should be made in the function stopRotateWheel() and startTime()
When the function is called, a variable called text holds the result ("Geography" or "Science", etc.).
From that, we can perform conditions based on the value of text and determine the total time of countdown, plus the link when the countdown expires.
Something like this:
function stopRotateWheel() {
clearTimeout(spinTimeout);
var degrees = startAngle * 180 / Math.PI + 90;
var arcd = arc * 180 / Math.PI;
var index = Math.floor((360 - degrees % 360) / arcd);
wheel.save();
wheel.font = '30px "Homestead-Inline", Helvetica, Arial';
var text = prize_descriptions[index];
//wheel.fillText(text, 250 - wheel.measureText(text).width / 2, 250 + 10);
wheel.restore();
document.getElementById('timer').innerHTML = "15";
document.getElementById('category').innerHTML = "Your Category is: " + text;
/*do an if else*/
if(text=="Geography")
{
counter = 5;
tt=setInterval(function(){startTime("www.geography.com")},1000);
/*countdown, and when timer expires... go to another link*/
}
else if (text=="Science")
{
//do the same as above :)
}
}
notice the code startTime("www.geography.com")? that's because we also modify function startTime to accept a parameter (in this case, the website) so that when the countdown is finished the webpage goes to that link :)
function startTime(gotoLink) {
if(counter == 0) {
/*go to that link */
window.location.replace(gotoLink)
} else {
counter--;
}
document.getElementById('timer').innerHTML = counter;
}
try it out!
I have written this code. I had programmed it in pure js,css,html5 before but it looks weird on iDevices so I thought I could make this in canvas easily too. But I ran into following problem.
You can see a condition where I check the angle of the text. I tried multiple things but still can't turn the text upside down on the other side of the "chart". Could anybody help me with that?
$(document).ready(function() {
var orange = "#ef5e09";
var c = $("#myChart");
var ctx = c.get(0).getContext("2d");
var dData = function() {
return Math.round(Math.random() * 90) + 10
};
var data = {
labels: ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"],
data: [dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData()]
}
function draw() {
//check canvas parent width and calculate dimensions
c.css("width", c.parent().width());
c.css("height", c.parent().width());
ctx.canvas.width = c.parent().width();
ctx.canvas.height = ctx.canvas.width;
var d = {
cX: ctx.canvas.width / 2,
cY: ctx.canvas.width / 2,
width: ctx.canvas.width,
height: ctx.canvas.height,
lineWidth: ctx.canvas.width * 0.00934579,
radius: ctx.canvas.width * 0.03,
cW: ctx.canvas.width * 0.002,
fW: ctx.canvas.width * 0.28
};
// draw bg circles
for (var i = 10; i > 0; i--) {
ctx.beginPath();
ctx.arc(d.cX, d.cY, i * d.radius, 0, 2 * Math.PI, false);
if (i % 2) {
ctx.fillStyle = '#f6f7f8';
ctx.fill();
} else {
ctx.fillStyle = '#fff';
ctx.fill();
}
ctx.lineWidth = d.cW;
ctx.strokeStyle = '#babbbc';
ctx.stroke();
}
var sa = 2 * Math.PI / data.data.length;
var font = d.width * (18 / 1000) + 'px Verdana';
for (var i = 0; i < data.data.length; i++) {
var v = 10 * d.radius * (data.data[i] / 100);
var nX = d.cX + v * Math.cos(i * sa);
var nY = d.cY + v * Math.sin(i * sa);
ctx.beginPath();
ctx.moveTo(d.cX, d.cY);
ctx.lineTo(nX, nY);
ctx.strokeStyle = orange;
ctx.lineWidth = d.lineWidth;
ctx.stroke();
var l = data.labels[i];
var nX = Math.floor(d.cX + 11 * d.radius * Math.cos(i * sa));
var nY = Math.floor(d.cY + 11 * d.radius * Math.sin(i * sa));
console.log(l + " [" + nX + ":" + nY + "]");
ctx.save();
var origAlign = ctx.textAlign;
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
//here's the edited part where I tried to rotate the text in place
ctx.translate(-ctx.measureText(l).width,d.width*(18/1000)/2);
ctx.rotate(Math.PI);
//end of edited part
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
}
ctx.restore();
}
}
draw();
$(window).resize(draw);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="col-xs-6">
<canvas id="myChart"></canvas>
</div>
Here's how to use transformations to rotate text around a centerpoint while keeping the text upright at any angle.
You can use context.translate + context.rotate to push the text outward from the centerpoint at an angle.
You can use context.scale to flip the text either vertically or horizontally as needed by the angle.
You can use context.textBaseline to keep the text displaying at a uniform distance from the centerpoint regardless of its angle.
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var angle=0;
var angleIncrement=Math.PI/180;
var count=0;
var cx=75;
var cy=75;
var radius=3;
var PI2=Math.PI*2;
ctx.beginPath();
ctx.arc(cx,cy,3,0,PI2);
ctx.fill();
requestAnimationFrame(animate);
function animate(time){
var PI2=Math.PI*2;
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
ctx.arc(cx,cy,3,0,PI2);
ctx.fill();
drawLabelAtAngle('Label #'+count,cx,cy,angle,radius);
angle+=angleIncrement;
angle=(angle+PI2)%PI2;
count++;
requestAnimationFrame(animate);
}
function drawLabelAtAngle(text,x,y,angle,offset){
// calc the angle clampled between 0 & PI*2
var normA=(angle+Math.PI*2)%(Math.PI*2);
// get ready to flip the text if it is on the left side
if(normA>=Math.PI*3/2 || normA<=Math.PI/2){
ctx.textAlign='left';
var flip=1;
offset+=5;
}else{
ctx.textAlign='right';
var flip=-1;
offset-=10;
}
// set the baseline to middle
ctx.textBaseline='middle';
// set [0,0] to [x,y]
ctx.translate(x,y);
// rotate
ctx.rotate(angle);
// if the text is on the left side, flip it for readability
ctx.scale(flip,flip);
// draw the text
ctx.fillText(text,offset,0);
// always clean up!
// reset transforms & text styling
ctx.setTransform(1,0,0,1,0,0);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=150 height=150></canvas>
When measuring text, you need to set font before measuring text.
When rotating around point (ex. middle of text) that is not origin, you need to translate, rotate, translate.
In your code, try replacing...
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
//here's the edited part where I tried to rotate the text in place
ctx.translate(-ctx.measureText(l).width,d.width*(18/1000)/2);
ctx.rotate(Math.PI);
//end of edited part
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
with...
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.translate(10.5 * d.radius + ctx.measureText(l).width / 2, 0);
ctx.rotate(Math.PI);
ctx.translate(-10.5 * d.radius - ctx.measureText(l).width / 2, 0);
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
How To Get The Value Of A Canvas . I have wheel which is rotating on mouse over the wheel stops now i want to echo out the value on which it was stopped. It is printing the whole array . Not the one on which the wheel stop.
$("#canvas").mouseover(function(){
backup= ctx;
alert(myData);
ctx = null;
});
this is the fiddle: https://jsfiddle.net/z61n9ccx/3/
Here is the full code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var PI2 = Math.PI * 2;
var myData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var cx = 150;
var cy = 150;
var radius = 150;
var wheel = document.createElement('canvas');
var wheelCtx = wheel.getContext('2d');
var indicator = document.createElement('canvas');
var indicatorCtx = indicator.getContext('2d');
var angle = PI2 - PI2 / 4;
var myColor = [];
for (var i = 0; i < myData.length; i++) {
myColor.push(randomColor());
}
makeWheel();
makeIndicator();
requestAnimationFrame(animate);
function makeWheel() {
wheel.width = wheel.height = radius * 2 + 2;
wheelCtx.lineWidth = 1;
wheelCtx.font = '40px Pacifico, cursive';
wheelCtx.textAlign = 'center';
wheelCtx.textBaseline = 'middle';
var cx = wheel.width / 2;
var cy = wheel.height / 2;
var sweepAngle = PI2 / myData.length;
var startAngle = 0;
for (var i = 0; i < myData.length; i++) {
// calc ending angle based on starting angle
var endAngle = startAngle + sweepAngle;
// draw the wedge
wheelCtx.beginPath();
wheelCtx.moveTo(cx, cy);
wheelCtx.arc(cx, cy, radius, startAngle, endAngle, false);
wheelCtx.closePath();
wheelCtx.fillStyle = myColor[i];
wheelCtx.strokeStyle = 'black';
wheelCtx.fill();
wheelCtx.stroke();
// draw the label
var midAngle = startAngle + (endAngle - startAngle) / 2;
var labelRadius = radius * .85;
var x = cx + (labelRadius) * Math.cos(midAngle);
var y = cy + (labelRadius) * Math.sin(midAngle);
wheelCtx.fillStyle = 'gold';
wheelCtx.fillText(myData[i], x, y);
wheelCtx.strokeText(myData[i], x, y);
// increment angle
startAngle += sweepAngle;
}
}
function makeIndicator() {
indicator.width = indicator.height = radius + radius / 10;
indicatorCtx.font = '40px Georgia';
indicatorCtx.textAlign = 'center';
indicatorCtx.textBaseline = 'middle';
indicatorCtx.fillStyle = 'skyblue';
indicatorCtx.strokeStyle = 'blue';
indicatorCtx.lineWidth = 1;
var cx = indicator.width / 2;
var cy = indicator.height / 2;
indicatorCtx.beginPath();
indicatorCtx.moveTo(cx - radius / 8, cy);
indicatorCtx.lineTo(cx, cy - indicator.height / 2);
indicatorCtx.lineTo(cx + radius / 8, cy);
indicatorCtx.closePath();
indicatorCtx.fillStyle = 'skyblue'
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.beginPath();
indicatorCtx.arc(cx, cy, radius / 3, 0, PI2);
indicatorCtx.closePath();
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.fillStyle = 'blue';
indicatorCtx.fillText('Prizes', cx, cy);
}
function animate(time) {
ctx.clearRect(0, 0, cw, ch);
ctx.translate(cw / 2, ch / 2);
ctx.rotate(angle);
ctx.drawImage(wheel, -wheel.width / 2, -wheel.height / 2);
ctx.rotate(-angle);
ctx.translate(-cw / 2, -ch / 2);
ctx.drawImage(indicator, cw / 2 - indicator.width / 2, ch / 2 - indicator.height / 2)
angle += PI2 / 360;
requestAnimationFrame(animate);
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
var backup = null;
$("#canvas").mouseover(function() {
backup = ctx;
alert(myData);
ctx = null;
});
$("#canvas").mouseout(function() {
// backup= ctx;
ctx = backup;
animate();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<canvas id="canvas" width="600" height="600" style="background-color:#ffff">
</canvas>
I added a counter, and then use that as a index: https://jsfiddle.net/Twisty/L6nws9yz/2/
HTML
<canvas id="canvas" width="310" height="310" style="background-color:#ffff">
</canvas>
<div id="counterBox">
<label>Counter:</label>
<span></span>
</div>
<div id="countBox">
<label>Index:</label>
<span></span>
</div>
JS
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var PI2 = Math.PI * 2;
var myData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var cx = 150;
var cy = 150;
var radius = 150;
var wheel = document.createElement('canvas');
var wheelCtx = wheel.getContext('2d');
var indicator = document.createElement('canvas');
var indicatorCtx = indicator.getContext('2d');
var currentSelection = 12;
var counter = 360;
var angle = PI2 - PI2 / 4;
var myColor = [];
for (var i = 0; i < myData.length; i++) {
myColor.push(randomColor());
}
makeWheel();
makeIndicator();
requestAnimationFrame(animate);
function makeWheel() {
wheel.width = wheel.height = radius * 2 + 2;
wheelCtx.lineWidth = 1;
wheelCtx.font = '40px Pacifico, cursive';
wheelCtx.textAlign = 'center';
wheelCtx.textBaseline = 'middle';
var cx = wheel.width / 2;
var cy = wheel.height / 2;
var sweepAngle = PI2 / myData.length;
var startAngle = 0;
for (var i = 0; i < myData.length; i++) {
// calc ending angle based on starting angle
var endAngle = startAngle + sweepAngle;
// draw the wedge
wheelCtx.beginPath();
wheelCtx.moveTo(cx, cy);
wheelCtx.arc(cx, cy, radius, startAngle, endAngle, false);
wheelCtx.closePath();
wheelCtx.fillStyle = myColor[i];
wheelCtx.strokeStyle = 'black';
wheelCtx.fill();
wheelCtx.stroke();
// draw the label
var midAngle = startAngle + (endAngle - startAngle) / 2;
var labelRadius = radius * .85;
var x = cx + (labelRadius) * Math.cos(midAngle);
var y = cy + (labelRadius) * Math.sin(midAngle);
wheelCtx.fillStyle = 'gold';
wheelCtx.fillText(myData[i], x, y);
wheelCtx.strokeText(myData[i], x, y);
// increment angle
startAngle += sweepAngle;
}
}
function makeIndicator() {
indicator.width = indicator.height = radius + radius / 10;
indicatorCtx.font = '40px Georgia';
indicatorCtx.textAlign = 'center';
indicatorCtx.textBaseline = 'middle';
indicatorCtx.fillStyle = 'skyblue';
indicatorCtx.strokeStyle = 'blue';
indicatorCtx.lineWidth = 1;
var cx = indicator.width / 2;
var cy = indicator.height / 2;
indicatorCtx.beginPath();
indicatorCtx.moveTo(cx - radius / 8, cy);
indicatorCtx.lineTo(cx, cy - indicator.height / 2);
indicatorCtx.lineTo(cx + radius / 8, cy);
indicatorCtx.closePath();
indicatorCtx.fillStyle = 'skyblue'
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.beginPath();
indicatorCtx.arc(cx, cy, radius / 3, 0, PI2);
indicatorCtx.closePath();
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.fillStyle = 'blue';
indicatorCtx.fillText('Prizes', cx, cy);
}
var lastloop = new Date;
var thisloop = new Date;
var fps = 0;
function animate(time) {
ctx.clearRect(0, 0, cw, ch);
ctx.translate(cw / 2, ch / 2);
ctx.rotate(angle);
ctx.drawImage(wheel, -wheel.width / 2, -wheel.height / 2);
ctx.rotate(-angle);
ctx.translate(-cw / 2, -ch / 2);
ctx.drawImage(indicator, cw / 2 - indicator.width / 2, ch / 2 - indicator.height / 2)
angle += PI2 / 360;
thisloop = new Date;
fps = 1000 / (thisloop - lastloop);
lastloop = thisloop;
counter--;
if (counter < 1) {
counter = 360;
}
$("#counterBox span").html(counter);
var index = counter / 30;
$("#countBox span").html(Math.round(index));
//$("#fpsBox span").html(fps);
requestAnimationFrame(animate);
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
var backup = null;
$("#canvas").mouseover(function() {
backup = ctx;
alert(myData[Math.round(counter / 30)-1]);
ctx = null;
});
$("#canvas").mouseout(function() {
// backup= ctx;
ctx = backup;
animate();
});
Counter is set to 360 and then each frame decreases it. Take that and divide by 30 (360 / 12), and you can count each wedge. I round up and now I have 0 - 11 count.
Update
I moved the Index into a global space. To make it more precise, I used the % operator like so:
counter--;
if (counter == 0) {
counter = 360;
}
$("#counterBox span").html(counter);
if (counter % 30 === 0) {
index--;
}
$("#countBox span").html(Math.round(index));
if (index === 0) {
index = 12;
}
When you mouse over, you get the selection:
$("#canvas").mouseover(function() {
backup = ctx;
alert(index);
ctx = null;
});
I wrapped everything in an IIFE so that there aren't any global variables.
Updated Example
It's important to note that the angle calculation is:
angle = degree * Math.PI / 180;
With that being said, you can calculate the current degree and normalize it using:
(angle * (180 / Math.PI)) % 360
I added a function called getValue which takes an angle parameter:
function getValue(angle) {
var degree = (angle * (180 / Math.PI)) % 360,
offsetIndex = (Math.floor(degree / sweepDegree) + offset) % myData.length,
normalizedIndex = Math.abs(offsetIndex - (myData.length - 1));
return myData[normalizedIndex];
}
It essentially calculates the current degree, normalizes it taking into account what the initial degree was when the animation was initialized (which is the offset). Then it divides the degree by the sweep degree, which is 30 in this case since there are 12 items (i.e., 360/12 === 30) and rounds down.
var sweepDegree = 360 / myData.length;
var offset = (360 - (angle * (180 / Math.PI)) % 360) / sweepDegree;
This should work for a varying number of array items. In other words, nothing is hardcoded for a set length of 12 items (like in your case), so it should work for any given number of items.
Then you can simply use the getValue function in the mouseover event listener:
Updated Example
$("#canvas").mouseover(function() {
// ...
alert(getValue(angle));
});
(function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var PI2 = Math.PI * 2;
var myData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var cx = 150;
var cy = 150;
var radius = 150;
var wheel = document.createElement('canvas');
var wheelCtx = wheel.getContext('2d');
var indicator = document.createElement('canvas');
var indicatorCtx = indicator.getContext('2d');
var angle = PI2 - PI2 / 4;
var sweepDegree = 360 / myData.length;
var offset = (360 - (angle * (180 / Math.PI)) % 360) / sweepDegree;
var myColor = [];
for (var i = 0; i < myData.length; i++) {
myColor.push(randomColor());
}
makeWheel();
makeIndicator();
requestAnimationFrame(animate);
function makeWheel() {
wheel.width = wheel.height = radius * 2 + 2;
wheelCtx.lineWidth = 1;
wheelCtx.font = '40px Pacifico, cursive';
wheelCtx.textAlign = 'center';
wheelCtx.textBaseline = 'middle';
var cx = wheel.width / 2;
var cy = wheel.height / 2;
var sweepAngle = PI2 / myData.length;
var startAngle = 0;
for (var i = 0; i < myData.length; i++) {
// calc ending angle based on starting angle
var endAngle = startAngle + sweepAngle;
// draw the wedge
wheelCtx.beginPath();
wheelCtx.moveTo(cx, cy);
wheelCtx.arc(cx, cy, radius, startAngle, endAngle, false);
wheelCtx.closePath();
wheelCtx.fillStyle = myColor[i];
wheelCtx.strokeStyle = 'black';
wheelCtx.fill();
wheelCtx.stroke();
// draw the label
var midAngle = startAngle + (endAngle - startAngle) / 2;
var labelRadius = radius * .85;
var x = cx + (labelRadius) * Math.cos(midAngle);
var y = cy + (labelRadius) * Math.sin(midAngle);
wheelCtx.fillStyle = 'gold';
wheelCtx.fillText(myData[i], x, y);
wheelCtx.strokeText(myData[i], x, y);
// increment angle
startAngle += sweepAngle;
}
}
function makeIndicator() {
indicator.width = indicator.height = radius + radius / 10;
indicatorCtx.font = '40px Georgia';
indicatorCtx.textAlign = 'center';
indicatorCtx.textBaseline = 'middle';
indicatorCtx.fillStyle = 'skyblue';
indicatorCtx.strokeStyle = 'blue';
indicatorCtx.lineWidth = 1;
var cx = indicator.width / 2;
var cy = indicator.height / 2;
indicatorCtx.beginPath();
indicatorCtx.moveTo(cx - radius / 8, cy);
indicatorCtx.lineTo(cx, cy - indicator.height / 2);
indicatorCtx.lineTo(cx + radius / 8, cy);
indicatorCtx.closePath();
indicatorCtx.fillStyle = 'skyblue'
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.beginPath();
indicatorCtx.arc(cx, cy, radius / 3, 0, PI2);
indicatorCtx.closePath();
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.fillStyle = 'blue';
indicatorCtx.fillText('Prizes', cx, cy);
}
function animate(time) {
if (ctx === null) {
return
}
ctx.clearRect(0, 0, cw, ch);
ctx.translate(cw / 2, ch / 2);
ctx.rotate(angle);
ctx.drawImage(wheel, -wheel.width / 2, -wheel.height / 2);
ctx.rotate(-angle);
ctx.translate(-cw / 2, -ch / 2);
ctx.drawImage(indicator, cw / 2 - indicator.width / 2, ch / 2 - indicator.height / 2)
angle += PI2 / 360;
requestAnimationFrame(animate);
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
var backup = null;
$("#canvas").mouseover(function() {
backup = ctx;
ctx = null;
alert(getValue(angle));
});
$("#canvas").mouseout(function() {
ctx = backup;
animate();
});
function getValue(angle) {
var degree = (angle * (180 / Math.PI)) % 360,
offsetIndex = (Math.floor(degree / sweepDegree) + offset) % myData.length,
normalizedIndex = Math.abs(offsetIndex - (myData.length - 1));
return myData[normalizedIndex];
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<canvas id="canvas" width="600" height="600" style="background-color:#ffff">
</canvas>