2014-11-25 3 views
0

일부 캔버스 애니메이션과 함께 타이머를 만들려고합니다. 애니메이션은 60fps로 설정된 함수 루프를 사용하여 캔바스를 새로 고침하고 객체를 다시 그립니다. 스톱워치를 만들 수있는 유일한 방법은 동일한 루프를 사용하여 프레임 당 밀리 초를 가져 와서 텍스트 개체에 추가하는 것입니다. 이 일을하는 더 효율적인 방법이 있는지 궁금한가요?60fps에서 캔버스 애니메이션과 함께 스톱워치/타이머 만들기

var frame = 0; 
canvas.setLoop(function() { 
    if(particle.x < 1080 && particle.x > 0){ 
     frame++; 
     particle.x = 540 + (acc*frame*frame)/120; 
     gField.t.text = "g = 9.81ms⁻²\nMass = "+particle.mass+"kg\nF = ma\nFrame: " + frame + "\nDistance: " + (particle.x - 540).toFixed(1); 
     stopwatch(); 
    }else{ 
     canvas.timeline.stop(); 
    } 
}) 
var sec = 0; 
var tsec = 0; 
var hsec = 0; 
function stopwatch(){ 
    hsec+= (5/3); 
    if(hsec >= 10){ 
     tsec++; 
     hsec = hsec -10; 
    } 
    if(tsec >= 10){ 
     sec++; 
     tsec = tsec-10; 
    } 
    time.text = (sec)+":"+(tsec)+(hsec).toFixed(0); 
} 
var clicks = 0 
control.button.bind("click tap", function() { 
    clicks++; 
    if(clicks == 1){ 
     canvas.timeline.start(); 
    }else{ 
     clicks = 0; 
     canvas.timeline.stop(); 
    } 
}) 

p.s. 이것은 역학 시뮬레이션 프로그램을위한 것입니다. 캔버스 애니메이션을 위해 oCanvas 라이브러리를 사용하고 있습니다.

+0

보증에 의해 60fps가 없다는 것을 명심하십시오. f. UR 클라이언트 PC가 느립니다. U는 Propper 시간을 얻으려면 Date()로 시간을 확인해야합니다. – Cracker0dks

+0

아마도 클라이언트의 FPS를 얻는 데 도움이 될 수 있습니다. http://stackoverflow.com/a/4787460/648350 – haxxxton

답변

2

사용 requestAnimationFrame이 자바 스크립트로 얻을 것이다 가장 정확한 타이머가 있으며, 보너스는 고해상도 타임 스탬프를 제공 할 것입니다 같이

var ctx = canvas.getContext('2d'), 
 
    startTime = null, 
 
    lastTime = null, // for scale 
 
    isRunning = false, 
 
    FPS = 1000/60, 
 
    x = 0, 
 
    dx = 4; // ideal frame rate 
 

 
function loop(timeStamp) { 
 

 
    if (!startTime) startTime = timeStamp; 
 
    
 

 
    var timeDiff = lastTime ? timeStamp - lastTime : FPS, 
 
     timeElapsed = timeStamp - startTime, 
 
     timeScale = timeDiff/FPS; // adjust variations in frame rates 
 

 
    lastTime = timeStamp; 
 
    
 
    ctx.clearRect(0,0,canvas.width, canvas.height); 
 

 
    // do your stuff using timeScale, ie: 
 
    // pos.x += velocity.x * timeScale 
 
    x += dx * timeScale; 
 
    if (x < 0 || x > canvas.width-1) dx = -dx; 
 
    
 
    ctx.fillRect(x,0,8,8); 
 
    ctx.fillText((timeElapsed*0.001).toFixed(4), 10, 50); 
 
    ctx.fillText(timeScale.toFixed(1), 10, 90); 
 

 
    if (isRunning) requestAnimationFrame(loop); 
 
} 
 

 
ctx.font = "40px sans-serif"; 
 

 
btnToggle.addEventListener("click", function() { 
 
    if (isRunning) { 
 
    isRunning = false; 
 
    this.innerHTML = "Start"; 
 
    } else { 
 
    startTime = lastTime = null; 
 
    isRunning = true; 
 
    requestAnimationFrame(loop) 
 
    this.innerHTML = "Stop"; 
 
    } 
 
}, false);
<canvas id=canvas width=360 height=100></canvas> 
 
<br><button id="btnToggle">Start</button>

으로 초기화 시작 시간은 null (또는 0)으로 초기화합니다. isRunning은 여기서 루프를 중지하는 방법에 대한 예 (false로 설정)로 사용됩니다.

timeScale은 프레임 속도 변동을 보완하는 데 사용됩니다. 루프가 60FPS에서 실행되지 않으면 timeScale이이를 보충합니다. FPS가 30 timeScale 인 경우 2 일 것이므로 시간에 따라 매개 변수를 올바르게 업데이트 할 수 있습니다.

+0

예! 이것은 내가하고 싶은 일에 완벽 해 보인다. 감사합니다 – JimiiBee

+0

루프 함수를 호출 할 때 timeStamp가 초기화되는 방법을 모르겠습니다. – JimiiBee

+0

'requestAnimationFrame (loop)'을 사용하여 루프를 시작하십시오. rAF가 초기화합니다. 희망이 도움이! – K3N

관련 문제