2016-08-29 142 views
1

我正在嘗試創建一個可以繪製類似於進度條的圓的動畫。我打算在旋轉木馬上使用它來跟蹤下一張幻燈片何時到來。我遇到的問題是我不知道如何改變動畫的持續時間。我嘗試調整幀速率,它可以工作,但動畫變得非常不穩定。 setInterval類型的作品,但它顯示整個圓圈,而不僅僅是我想要的一部分,所以我不能正確地計時。我需要能夠控制動畫的速度,減慢動畫的速度,而不會讓它停頓。我正在處理的代碼如下。使用請求動畫幀更改畫布動畫的持續時間

<script>  
    (function() { 
     var requestAnimationFrame = window.requestAnimationFrame || 
            window.mozRequestAnimationFrame || 
            window.webkitRequestAnimationFrame || 
            window.msRequestAnimationFrame; 
            window.requestAnimationFrame = requestAnimationFrame; 
    })(); 
     var canvas = document.getElementById('myCanvas'); 
     var context = canvas.getContext('2d'); 
     var centerX = canvas.width/2; 
     var centerY = canvas.height/2; 
     var radius = 90; 
     var endPercent = 85; 
     var curPerc = 0; 
     var circ = -Math.PI; 
     var quart = -(Math.PI * 2) + 1; 

     function animate(current) { 
      context.clearRect(0, 0, canvas.width, canvas.height); 
      context.beginPath(); 
      context.arc(centerX, centerY, radius, -(quart), ((circ) * current) - quart, true); 
      context.lineWidth = 3; 
      context.strokeStyle = '#000'; 
      context.stroke(); 
      curPerc++; 
      if (curPerc < endPercent) { 
       requestAnimationFrame(function() { 
       animate(curPerc/100) 
       }); 
      } 
     } 

    animate(); 
</script> 
+0

這裏是一個[好文章](https://www.viget.com/articles/time-based-animation)和[github上要旨](HTTPS://要旨。 github.com/greypants/3739036)伴隨它,基於時間的畫布動畫。 –

回答

3

​​確實在回調參數中傳遞了高分辨率時間戳。因此,您可以使用它來確定您當前動畫中的位置,並使用此增量時間來設置您的頭寸變量,而不是curPerc++

這裏是一個天真的實現。

var canvas = document.getElementById('myCanvas'); 
 
var context = canvas.getContext('2d'); 
 
var centerX = canvas.width/2; 
 
var centerY = canvas.height/2; 
 
var radius = 90; 
 
var endPercent = 85; 
 
var quart = -(Math.PI * 2) + 1; 
 
var startTime = null; 
 
var duration = null; 
 

 
function animate(time) { 
 

 
    if (!startTime) { 
 
    startTime = time; 
 
    } 
 

 
    var delta = Math.min(1, (time - startTime)/duration); 
 
    var curPerc = ((-2 * Math.PI)/100) * (endPercent * delta); 
 

 
    context.clearRect(0, 0, canvas.width, canvas.height); 
 
    context.beginPath(); 
 
    context.arc(centerX, centerY, radius, -quart, curPerc - quart, true); 
 
    context.stroke(); 
 

 
    if (delta < 1) { 
 
    requestAnimationFrame(animate); 
 
    } else { 
 
    startTime = null; 
 
    slider.disabled = false; 
 
    } 
 
} 
 

 
var startAnim = function() { 
 
    context.lineWidth = 3; 
 
    context.strokeStyle = '#000'; 
 

 
    slider.disabled = true; 
 
    duration = +slider.value; 
 
    l.textContent = duration + 'ms'; 
 
    requestAnimationFrame(animate); 
 
}; 
 
slider.onchange = startAnim; 
 
startAnim();
<p>use the slider to update the animation's duration</p> 
 
<input type="range" min="250" max="9000" value="2000"id="slider" /> 
 
<label id="l"></label><br> 
 
<canvas id="myCanvas" height="300"></canvas>

+1

@markE,你是正確的編輯。通常我甚至在我的anim函數頂部放置的'if(delta> = 1)'中添加一個「draw last frame」調用。在OP的結構中,這樣做太懶惰了。 – Kaiido

+0

非常感謝。我搜遍了很多東西,找不到正確的答案。 – Orophen

相關問題