optimize rAF calls
This commit is contained in:
parent
059441e13c
commit
619fae1ee2
|
|
@ -1,4 +1,5 @@
|
||||||
import { ReactiveController, ReactiveControllerHost } from '@lit/reactive-element';
|
import { ReactiveController, ReactiveControllerHost } from '@lit/reactive-element';
|
||||||
|
import { requestAnimationFrame, cancelAnimationFrame } from './rAF';
|
||||||
|
|
||||||
export interface AnimationFrameControllerHost extends ReactiveControllerHost {
|
export interface AnimationFrameControllerHost extends ReactiveControllerHost {
|
||||||
tick(): void;
|
tick(): void;
|
||||||
|
|
@ -7,7 +8,6 @@ export interface AnimationFrameControllerHost extends ReactiveControllerHost {
|
||||||
|
|
||||||
export class AnimationFrameController implements ReactiveController {
|
export class AnimationFrameController implements ReactiveController {
|
||||||
#host;
|
#host;
|
||||||
#rAFId = -1;
|
|
||||||
#lastTime = 0;
|
#lastTime = 0;
|
||||||
#dtAccumulator = 0;
|
#dtAccumulator = 0;
|
||||||
#fixedTimestep = 1 / 60;
|
#fixedTimestep = 1 / 60;
|
||||||
|
|
@ -16,8 +16,9 @@ export class AnimationFrameController implements ReactiveController {
|
||||||
return this.#fixedTimestep;
|
return this.#fixedTimestep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#isRunning = false;
|
||||||
get isRunning() {
|
get isRunning() {
|
||||||
return this.#rAFId !== -1;
|
return this.#isRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(host: AnimationFrameControllerHost) {
|
constructor(host: AnimationFrameControllerHost) {
|
||||||
|
|
@ -36,7 +37,7 @@ export class AnimationFrameController implements ReactiveController {
|
||||||
}
|
}
|
||||||
|
|
||||||
#tick = (timestamp: DOMHighResTimeStamp = performance.now()) => {
|
#tick = (timestamp: DOMHighResTimeStamp = performance.now()) => {
|
||||||
this.#rAFId = requestAnimationFrame(this.#tick);
|
requestAnimationFrame(this.#tick);
|
||||||
|
|
||||||
const actualDelta = (timestamp - this.#lastTime) * 0.001;
|
const actualDelta = (timestamp - this.#lastTime) * 0.001;
|
||||||
this.#lastTime = timestamp;
|
this.#lastTime = timestamp;
|
||||||
|
|
@ -56,10 +57,12 @@ export class AnimationFrameController implements ReactiveController {
|
||||||
if (this.isRunning) return;
|
if (this.isRunning) return;
|
||||||
|
|
||||||
this.#lastTime = 0;
|
this.#lastTime = 0;
|
||||||
requestAnimationFrame(this.#tick);
|
this.#isRunning = true;
|
||||||
|
this.#tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
cancelAnimationFrame(this.#rAFId);
|
cancelAnimationFrame(this.#tick);
|
||||||
|
this.#isRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
const callbacks = new Set<FrameRequestCallback>();
|
||||||
|
let rAFId = -1;
|
||||||
|
|
||||||
|
function onRAF(time: DOMHighResTimeStamp) {
|
||||||
|
rAFId = -1;
|
||||||
|
const values = Array.from(callbacks);
|
||||||
|
callbacks.clear();
|
||||||
|
values.forEach((callback) => callback(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch multiple callbacks into a single rAF for better performance
|
||||||
|
export function requestAnimationFrame(callback: FrameRequestCallback) {
|
||||||
|
if (callbacks.size === 0) {
|
||||||
|
rAFId = window.requestAnimationFrame(onRAF);
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function cancelAnimationFrame(callback: FrameRequestCallback) {
|
||||||
|
callbacks.delete(callback);
|
||||||
|
|
||||||
|
if (callbacks.size === 0) {
|
||||||
|
window.cancelAnimationFrame(rAFId);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue