我正在研究幸运抽奖号码的小项目,用户点击按钮后可以旋转但不能自动完成,意味着我想在时间到达轮子旋转后显示倒计时。我使用了set Interval方法,但它不起作用。
window.onload = function () {
var fiveMinutes = 10 * 1,
display = document.querySelector('#count');
startTimer(fiveMinutes, display);
};
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function ()
{
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "Wheel Will Spin After: "+minutes + ":" + seconds;
if (--timer < 0) {
//timer = duration;
spin();
if(timer<=-1)
{
display.textContent = "Wheel Will Spin After: ";
}
}
}, 1000);
var colors = ["#B8D430", "#3AB745", "#029990", "#3501CB",
"#2E2C75", "#673A7E", "#CC0071", "#F80120",
"#F35B20", "#FB9A00", "#FFCC00", "#FEF200","#FEFAAA","#FEFA1A"];
var restaraunts = ["1", "2", "3", "4","5", "6", "7", "8","9", "10", "11", "12","13","14"];
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 = 200;
var textRadius = 160;
var insideRadius = 125;
ctx = canvas.getContext("2d");
ctx.clearRect(0,0,500,500);
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.font = 'bold 20px Times New Roman';
for(var i = 0; i < 14; i++) {
var angle = startAngle + i * arc;
ctx.fillStyle = colors[i];
ctx.beginPath();
ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
ctx.arc(250, 250, 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(250 + Math.cos(angle + arc / 2) * textRadius, 250 + Math.sin(angle + arc / 2) * textRadius);
ctx.rotate(angle + arc / 2 + Math.PI / 2);
var text = restaraunts[i];
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
}
//Arrow
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
ctx.lineTo(250 + 0, 250 - (outsideRadius - 13));
ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
ctx.fill();
}
}
function spin() {
spinAngleStart = Math.random() * 10 + 10;
spinTime = 5;
spinTimeTotal = Math.random() * 3 + 4 * 2000;
rotateWheel();
}
function rotateWheel() {
spinTime += 20;
if(spinTime >= spinTimeTotal) {
stopRotateWheel();
return;
}
var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
startAngle += (spinAngle * Math.PI / 180);
drawRouletteWheel();
spinTimeout = setTimeout('rotateWheel()', 10);
}
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 12px sans-serif';
var text = restaraunts[index]
//ctx.fillText(text, 250 - ctx.measureText(text).width / 2, 250 + 10);
//window.location = "navto://"+restaraunts[index]+"_stack";
//alert(text);
document.getElementById("msg").innerHTML=text;
ctx.restore();
}
function easeOut(t, b, c, d) {
var ts = (t/=d)*t;
var tc = ts*t;
return b+c*(tc + -3*ts + 3*t);
}
draw();
}
<html>
<body>
<div id= "count" class="category_heading" >Wheel Will Spin After: </div>
<div id= "msg" class="category_heading" >LUCKY NUMBER IS : </div>
<canvas id="wheelcanvas" width="500" height="500"></canvas>
</body>
</html>
答案 0 :(得分:1)
首先是解决方案。取代
spinTimeout = setTimeout('rotateWheel()', 10);
与
spinTimeout = setTimeout( rotateWheel, 10);
发生错误的原因是rotateWheel
是startTimer
函数中的嵌套函数,而不是全局范围。作为文本传递给setTimeout的代码片段"rotateWheel()"
被编译为全局范围内的函数,该函数在执行时无法找到rotateWheel
函数。用函数引用(在范围内)替换文本消除了首先编译源文本的需要。
一般情况下,请避免在代码中使用JavaScript源代码段,除非它是一个快速而肮脏的解决方案,而不是其他人会看到的内容: - )。
我认为这是正在进行的工作,在代码完成之前可能会有更多错误。祝好运。
<小时/> 响应评论,轮子继续旋转,因为在spin()
变为负数后,在每个间隔计时器回调期间调用timer
。
var timerId = setInterval(function ()
{
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "Wheel Will Spin After: "+minutes + ":" + seconds;
if (--timer < 0) {
//timer = duration;
spin();
clearInterval( timerId)
display.textContent = "Wheel Will Spin After: ";
}`
}, 1000);
上面的解决方案是调用spin
一次,然后停止间隔计时器。请注意,if( --timer < 0)
后跟if(timer<=-1)
有效地测试整数的相同条件,这意味着不需要进行第二次测试。