1 분 소요

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)});	
}

카테고리:

업데이트:

댓글남기기