2015-12-15 127 views
1

我有这个http://jsfiddle.net/e7fwt4wb/!在HTML5画布中旋转轮盘 - 正常工作时,当我调用方法旋转时,轮盘被旋转并停在随机数字的数组中!我怎样才能调用函数传递一个参数来停止在我的数组数组的位置?HTML5帆布Roullete

<script type="text/javascript"> 
var colors = ["#336600", "#660000", "#000000", "#660000", 
    "#000000", "#660000", "#000000", "#660000", 
    "#000000", "#660000", "#000000", "#660000", "#000000", "#660000", "#000000"]; 
var numbers = ["0", "1", "8", "2", 
    "9", "3", "10", "4", 
    "11", "5", "12", "6", "13", "7", "14"]; 

var startAngle = 0; 
var arc = Math.PI/6; 
var spinTimeout = null; 

var spinArcStart = 10; 
var spinTime = 0; 
var spinTimeTotal = 0; 

var ctx; 

function drawRouletteWheel() { 
    var canvas = document.getElementById("canvas"); 
    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 18px Helvetica, Arial'; 

     for (var i = 0; i < 12; 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 = "white"; 
      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 = numbers[i]; 
      ctx.fillText(text, -ctx.measureText(text).width/2, 0); 
      ctx.restore(); 
     } 

     //Arrow 
     ctx.fillStyle = "yellow"; 
     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 = 0; 
    spinTimeTotal = Math.random() * 3 + 4 * 1500; 
    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 Helvetica, Arial'; 
    ctx.textAlign = "center"; 
    var text = numbers[index] 
    ctx.fillStyle = colors[index]; 
    ctx.fillText("Rolled: " + text, 250 - ctx.measureText(text).width/2, 250 + 10); 
    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); 
} 

drawRouletteWheel(); 
</script> 
+0

以下是先前的问答,展示如何停止以特定角度旋转:http://stackoverflow.com/questions/29364360/canvas-wheel-of-fortune-stop-at-specific-spot/29375395#29375395 – markE

+0

Marke,我试图在过去的两天内调整我的轮子财富画布,以便在您告诉我的QA中使用您的画布,但我无法弄清楚如何适应!你能帮我吗? –

+0

**当然......我会帮助** :-)我已经发布了一个答案,展示了如何旋转轮子(使用缓动)并停在轮子上所需的数字上。祝你的项目好运! – markE

回答

2

这是如何旋转你的车轮,并停在车轮上所需的数字。

要使用彭纳的缓动式旋转的轮子,你需要定义这4个属性:

  • 动画
  • 的总变化的开始角度的电流经过的时间所需角度将车轮旋转至所需数量
  • 动画的总持续时间

考虑您可以将宽松式的动画期间计算在任何时候车轮角1这4个属性:

// t: current time inside duration, 
// b: beginning value, 
// c: total change from beginning value, 
// d: total duration 
function easeOutQuart(t, b, c, d){ 
    // return the current eased value based on the current time 
    return -c * ((t=t/d-1)*t*t*t - 1) + b; 
} 

例如,假设你想在一个持续旋转数9的口袋2秒。然后这些属性值将适用:

  • 当前经过的时间:800ms(例如),
  • 开始车轮的角度:0 radians,旋转到数9需要在角
  • 总变化:3.6652 radians
  • 总工期:2000ms

而且你可以在800ms在这样的计算车轮转动的角度有所缓解:

easeOutQuart(800,0,3.6652,2000); 

三所需彭纳属性是“吉文斯”,但旋转到数9所需的总变化是这样计算的:

// "9" is element#4 in numbers[] 
var indexOfNumber9 = 4; 

// calc what angle each number occupies in the circle 
var angleSweepPerNumber = (Math.PI*2)/totalCountOfNumbersOnWheel; 

// calc the change in angle required to rotate the wheel to number-9 
var endingAngleAt9 = (Math.PI*2) - angleSweepPerNumber * (indexOfNumber9+1); 

// the arrow is at the top of the wheel so rotate another -PI/2 (== -90 degrees) 
endingAngleAt9 -= Math.PI/2; 

// endingAngle is now at the leading edge of the wedge 
// so rotate a bit further so the array is clearly inside wedge#9 
endingAngleAt9 += Math.random()*angleSweepPerNumber; 

下面是示例代码和一个演示:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 

 
var colors = ["#336600", "#660000", "#000000", "#660000", 
 
       "#000000", "#660000", "#000000", "#660000", 
 
       "#000000", "#660000", "#000000", "#660000", "#000000", "#660000", "#000000"]; 
 
var numbers = ["0", "1", "8", "2", 
 
       "9", "3", "10", "4", 
 
       "11", "5", "12", "6", "13", "7", "14"]; 
 
var pocketCount=12; 
 
var cheatText=numbers[4]; 
 
$('#cheat').text('Stop on '+cheatText); 
 

 
var cw=canvas.width=ch=canvas.height=500; 
 
var cx=cw/2; 
 
var cy=ch/2; 
 

 
// wheel & arrow are used often so cache them 
 
var wheelCanvas=drawRouletteWheel(); 
 
var arrow=drawArrow(); 
 

 
var wheel={ 
 
    cx:cw/2, 
 
    cy:ch/2, 
 
    radius:Math.min(cw,ch)/2-20, 
 
    startAngle:0, 
 
    endAngle:Math.PI*4+cheatingSpin(cheatText), 
 
    totalSteps:360, 
 
    currentStep:0, 
 
} 
 

 
drawAll(wheel); 
 

 
$('#spin').click(function(){requestAnimationFrame(animate);$(this).hide()}); 
 

 

 
// funcs 
 

 
function cheatingSpin(hit){ 
 
    var PI=Math.PI; 
 
    var PI2=PI*2; 
 
    var index=numbers.indexOf(cheatText); 
 
    var pocketSweep=PI2/pocketCount; 
 
    // cheatText not in numbers[]? -- then spin randomly 
 
    if(index<0){return(PI2*2+Math.random()*PI2);} 
 
    // if cheating, calc random endAngle inside desired number's pocket 
 
    return((PI2-pocketSweep*(index+1))+Math.random()*pocketSweep-PI/2); 
 
} 
 

 
function animate(time){ 
 
    if(wheel.currentStep>wheel.totalSteps){return;} 
 
    drawAll(wheel); 
 
    wheel.currentStep++; 
 
    requestAnimationFrame(animate); 
 
} 
 

 
function easing(w){ 
 
    var t=w.currentStep; 
 
    var b=w.startAngle; 
 
    var d=w.totalSteps; 
 
    var c=w.endAngle-w.startAngle; 
 
    // Penner's OutQuart 
 
    return (-c*((t=t/d-1)*t*t*t-1)+b+w.startAngle);  
 
} 
 

 
function drawAll(w){ 
 
    var angle=easing(w); 
 
    ctx.clearRect(0,0,cw,ch); 
 
    ctx.translate(cx,cy); 
 
    ctx.rotate(angle); 
 
    ctx.drawImage(wheelCanvas,-wheelCanvas.width/2,-wheelCanvas.height/2); 
 
    ctx.rotate(-angle); 
 
    ctx.translate(-cx,-cy); 
 
    ctx.drawImage(arrow,cx-arrow.width/2,44); 
 
} 
 

 
function drawRouletteWheel() { 
 
    var outsideRadius = 200; 
 
    var textRadius = 160; 
 
    var insideRadius = 125; 
 
    var canvas = document.createElement("canvas"); 
 
    var ctx = canvas.getContext("2d"); 
 
    canvas.width=canvas.height=outsideRadius*2+6; 
 
    var x=outsideRadius+3; 
 
    var y=outsideRadius+3; 
 
    var arc = Math.PI/(pocketCount/2); 
 
    ctx.strokeStyle = "black"; 
 
    ctx.lineWidth = 2; 
 
    ctx.font = 'bold 18px Helvetica, Arial'; 
 
    // wheel 
 
    for (var i = 0; i < pocketCount; i++) { 
 
    var angle = i * arc; 
 
    ctx.fillStyle = colors[i]; 
 
    ctx.beginPath(); 
 
    ctx.arc(x,y, outsideRadius, angle, angle + arc, false); 
 
    ctx.arc(x,y, 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 = "white"; 
 
    ctx.translate(x+Math.cos(angle + arc/2) * textRadius, 
 
        y+Math.sin(angle + arc/2) * textRadius); 
 
    ctx.rotate(angle + arc/2 + Math.PI/2); 
 
    var text = numbers[i]; 
 
    ctx.fillText(text, -ctx.measureText(text).width/2, 0); 
 
    ctx.restore(); 
 
    } 
 
    // 
 
    return(canvas); 
 
} 
 

 
function drawArrow(){ 
 
    var canvas = document.createElement("canvas"); 
 
    var ctx = canvas.getContext("2d"); 
 
    canvas.width=18; 
 
    canvas.height=18; 
 
    //Arrow 
 
    ctx.fillStyle = "yellow"; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(5,0); 
 
    ctx.lineTo(13,0); 
 
    ctx.lineTo(13,10); 
 
    ctx.lineTo(18,10); 
 
    ctx.lineTo(9,18); 
 
    ctx.lineTo(0,10); 
 
    ctx.lineTo(5,10); 
 
    ctx.lineTo(5,0); 
 
    ctx.fill(); 
 
    return(canvas); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; background:lightgray; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<span id=cheat>Stop on this number</span> 
 
<button id=spin>Spin</button><br> 
 
<canvas id="canvas" width=300 height=300></canvas>

+0

尼斯市场!非常感谢你! :) –

+0

谢谢你这个..我想显示警告消息,当它停止像警报(cheatText);所以我应该把这个代码放在哪里? –

+0

@KuldeePChoudharY。别客气。您可以将完成的警报放在'animate'函数的'if'代码块中。 – markE

1

在您的代码中,通过设置spinAngleStart和spinTimeTotal,停止位置在函数旋转中被固定。

function spin() { 
    spinAngleStart = Math.random() * 10 + 10; 
    spinTime = 0; 
    spinTimeTotal = Math.random() * 3 + 4 * 1500; 
    rotateWheel(); 
} 

你应该写这样的伪代码

function setStopIndex(index) { 
    // compute and set spinAngleStart and spinTimeTotal according 
    // to index position 
    spinAngleStart = ... 
    spinTimeTotal = ... 
    spinTime = 0; 
} 

然后修改旋转功能,这样的功能:

function spin(stopIndex) { 
    setStopIndex(index) { 
    rotateWheel(); 
} 

上点击,调用旋(stopIndex),与定义的索引。

+0

对不起,但我是新的HTML5和帆布!我如何根据索引位置计算并设置spinAngleStart和spinTimeTotal? –

+1

这是一个javascript问题,而不是html5 + canvas。查看rotateWheel函数,查看每次调用时旋转多少轮,然后进行数学运算! –