requestAnimationFrame 사용법

requestAnimationFrame 사용법 updated_at: 2023-07-20 16:06

requestAnimationFrame 사용법

사용법

requestAnimationFrame 을 사용하는 방법은 많으나 사용에 따라 간혹 에러 등이 발생한다.

requestAnimationFrame(this.animate);
requestAnimationFrame(this.animate()); // NOT WORK
requestAnimationFrame(() => this.animate());  // NOT Recommand
requestAnimationFrame(() => this.animate);  // NOT WORK

추천(가장 추천하는 형식)

animate 함수는 변수로 정의하여 사용하기를 추천드립니다.
또한 초기호출시는 'requestAnimationFrame(this.animate);' 처럼 사용하길..

requestAnimationFrame(this.animate);
// window.requestAnimationFrame 처럼 window 를 붙이고 안붙이고는 자유.. (현재 일반적인 브라우저에서는 둘다 호환됨)

animate = (time: number) => {  
  requestAnimationFrame(this.animate);
}

cancelAnimationFrame

private anmationFramId: any;
..........
this.anmationFramId = requestAnimationFrame(this.animate);

animate = (time: number) => {  
  this.anmationFramId = requestAnimationFrame(this.animate);
}
..........

cancelAnimationFrame(this.anmationFramId);

경우에 따라 동작하거나 잘못된 사용예제

requestAnimationFrame(() => 메쏘드); 처럼 사용할 경우는 반드시 메쏘드로 정의하여야 한다.

requestAnimationFrame(() => this.animate); // 동작을 안함
animate = () => {}
requestAnimationFrame(() => this.animate()); // 동작은 하지만 time값을 받아오지 못함
animate(time?: number) {} 

호출시 requestAnimationFrame 없이 바로 호출 할 경우

this.animate(); // 동작은 하나 아래의 초기  time값을 받아 오지 못함
this.animate; // 동작안함

animate = (time?: number) => {  
  requestAnimationFrame(this.animate); // 이 이후에는 정상적으로 time값을 받아옮
}

animate 가 메소드로 정의된 경우

requestAnimationFrame(() => this.animate); // Not work (아래는 메소드로 정의하였으나 변수로 호출)
requestAnimationFrame(this.animate3()); // 문법상 맞지 않음
requestAnimationFrame(() => this.animate()); // Not recommand - time 값이 언제나 undefined
this.animate(); // 위와 동일한 결과

animate(time?: number)  { // 
  // requestAnimationFrame(this.animate()); // Not work
  // requestAnimationFrame(() => this.animate()); // Not recommand
  requestAnimationFrame(this.animate.bind(this)); // OK (동작은 함)
}

bind를 사용할 경우

animate() {
  requestAnimationFrame(this.animate.bind(this)); // OK request next update
}

경과시간 구하기

requestAnimationFrame 이 실행된 후 다시 실행되기까지의 시간을 구한다.

requestAnimationFrame(this.animate);
// window.requestAnimationFrame 처럼 window 를 붙이고 안붙이고는 자유.. (현재 일반적인 브라우저에서는 둘다 호환됨)

animate = (time: number) => {  
  let now = new Date().getTime();
  let timeSince = now - this.latestTap;
  this.latestTap = now;
  requestAnimationFrame(this.animate);
}

Object 이동 샘플

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-root',
  template:`<canvas #canvasId></canvas>`
})
export class AnimationFrameComponent1 implements AfterViewInit{
  @ViewChild('canvasId', {static: true}) canvasRef: ElementRef<HTMLCanvasElement> = {} as ElementRef;
  private ctx: any;
  private canvas: any;
  private position = {x:0, y:0};
  
  constructor(
  ) { }

  ngAfterViewInit(){

    this.canvas = this.canvasRef.nativeElement;
    this.ctx = this.canvas.getContext('2d');

    this.animate();
  }

  private draw() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

    this.position.x += 0.1
    this.position.y += 0.1

    this.ctx.fillRect(this.position.x, this.position.y, 50, 50);
    this.ctx.fillStyle = "#FFD662";
  }

  animate() {  
    this.draw();
    // window.requestAnimationFrame(() => this.animate()); // OK
    requestAnimationFrame(() => this.animate()); // OK window. 를 생략할 수 있다
    // requestAnimationFrame(this.animate.bind(this)); // OK request next update
    // requestAnimationFrame(this.animate); Error 이렇게 사용할 경우 animate 함수 안의   this.draw()를 인지하지못함
  }
}
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1

질문 및 답글