2015-12-15 1 views
1

У меня есть это http://jsfiddle.net/e7fwt4wb/! рулонье вращается в html5, как правило, работает с холстом, когда я вызываю метод spin, рулетка вращается и останавливается в случайном числе моего массива чисел! Как я могу вызвать функцию, передающую параметр для остановки в позиции моего массива чисел?HTML5 Холст Рулетка

<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 свойства:

  • Текущее истекшее время анимации
  • Начинающему угол колеса
  • Общее изменение в угол, необходимый для поворота колеса до нужного номера
  • Общая продолжительность анимации

Учитывая эти 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,

И вы можете рассчитать облегчили угол поворота колеса на 800 мс, как это:

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

Nice Marke! Большое спасибо! :) –

+0

Спасибо за это. Я хочу показать предупреждающее сообщение, когда он остановится, как alert (cheatText); так где я должен положить этот код? –

+0

@ KuldeePChoudharY. Пожалуйста. Вы можете поместить свое законченное предупреждение в блок кода 'if' в' animate'. – 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, чтобы увидеть, сколько колес вращается при каждом вызове, и делайте математику! –