requestAnimationFrame 사용법
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()를 인지하지못함
}
}