[JS]canvas 4 (with React)
cancelAnimationFrame을 이용한 animation 취소
cancelAnimationFrame()
을 이용하여 requestAnimationFrame()
을 취소 할 수 있다.
requestAnimationFrame()
은 timerId라는 값을 반환한다.
timerId = requsetAnimationFrame(draw);
이 값을
cancelAnimationFrame()
에 넣어주면 animation을 취소 할 수 있다.
cancelAnimationFrame(timerId);
이를 활용하여 특정 조건을 만족하면 동작을 멈추는 코드를 작성 할 수 있다. 예를들어 캔버스의 끝에 도달하면 움직임을 멈추는 공을 그리는 코드는 다음과 같다.
function draw(){
ctx.clearRect(0,0,canvasRef.current.width,canvasRef.currentheight);
ctx.beginPath();
ctx.arc(xPos,200,10,0,toRadian(360),false);
ctx.fill();
timerId = requestAnimationFrame(draw)
if(xPos >= canvasRef.current.width-10){
cancelAnimationFrame(timerId);
}
xPos+=10;
}
원의 x좌표값 xPos
가 캔버스 width에서 원의 반지름 10
을 뺀 위치에 도달했을때 cancelAnimationFrame(timerId)
를 호출하면 움직이던 공이 캔버스의 끝에 도달했을때 멈추게 된다.
처음 위 코드를 작성할 때 캔버스의 끝에 도달하지 않았는데도 공이 멈췄는데 내가 코드를 잘못 작성한 것이었다.
- 처음 작성한 코드(오류)
function draw(){
ctx.clearRect(0,0,canvasRef.current.width,canvasRef.currentheight);
ctx.beginPath();
ctx.arc(xPos,200,10,0,toRadian(360),false);
ctx.fill();
xPos+=10;
timerId = requestAnimationFrame(draw)
if(xPos >= canvasRef.current.width-10){
cancelAnimationFrame(timerId);
}
}
xPos+=10;
이 코드의 위치가 원인이었다. 10을 미리 증가시킨 상태에서 if문으로 조건을 검사했기 때문에 원의 좌표가width-10
에서 멈추지 않고width-20
에서 멈췄던 것이다.
그리고 캔버스를 클릭 했을때 원의 움직임을 멈추기 위해 캔버스에 event를 추가 하려했는데, 다음과 같이 <canvas>
태그에 onClick
으로 이벤트를 추가하니 제대로 동작하지 않았다.
<canvas className="canvas" ref={canvasRef} width="600" height="400" onClick={()=>{cancelAnimationFrame(timerId)};}></canvas><br/>
이전 포스팅 ‘canvas 1’에서 draw함수를 호출 할 때 if(ctx!=null)을 감싸주는 것 처럼 React상에서 useEffect를 포함한 함수 선언과 정의하는 순서 때문에 제대로 작동하지 않는듯 하다.
아래와 같이 addEventListener
에서 click 이벤트로 추가하니 잘 동작하였다.
if(ctx!=null){
draw();
canvasRef.current.addEventListener('click',()=>{cancelAnimationFrame(timerId)});
}
댓글남기기