@lightningjs/renderer
Version:
Lightning 3 Renderer
87 lines • 3.36 kB
JavaScript
import { Platform } from '../Platform.js';
export class WebPlatform extends Platform {
////////////////////////
// Platform-specific methods
////////////////////////
createCanvas() {
const canvas = document.createElement('canvas');
return canvas;
}
getElementById(id) {
return document.getElementById(id);
}
////////////////////////
// Update loop
////////////////////////
startLoop(stage) {
let isIdle = false;
let lastFrameTime = 0;
const runLoop = (currentTime = 0) => {
const targetFrameTime = stage.targetFrameTime;
// Check if we should throttle this frame
if (targetFrameTime > 0 &&
currentTime - lastFrameTime < targetFrameTime) {
// Too early for next frame, schedule with setTimeout for precise timing
const delay = targetFrameTime - (currentTime - lastFrameTime);
setTimeout(() => requestAnimationFrame(runLoop), delay);
return;
}
stage.updateFrameTime();
stage.updateAnimations();
if (!stage.hasSceneUpdates()) {
// We still need to calculate the fps else it looks like the app is frozen
stage.calculateFps();
if (targetFrameTime > 0) {
// Use setTimeout for throttled idle frames
setTimeout(() => requestAnimationFrame(runLoop), Math.max(targetFrameTime, 16.666666666666668));
}
else {
// Use standard idle timeout when not throttling
setTimeout(() => requestAnimationFrame(runLoop), 16.666666666666668);
}
if (!isIdle) {
stage.shManager.cleanup();
stage.eventBus.emit('idle');
isIdle = true;
}
if (stage.txMemManager.checkCleanup() === true) {
stage.txMemManager.cleanup(false);
}
stage.flushFrameEvents();
return;
}
isIdle = false;
stage.drawFrame();
stage.flushFrameEvents();
// Schedule next frame
if (targetFrameTime > 0) {
// Use setTimeout + rAF combination for precise FPS control
const nextFrameDelay = Math.max(0, targetFrameTime - (performance.now() - currentTime));
setTimeout(() => requestAnimationFrame(runLoop), nextFrameDelay);
}
else {
// Use standard rAF when not throttling
requestAnimationFrame(runLoop);
}
};
requestAnimationFrame(runLoop);
}
////////////////////////
// ImageBitmap
////////////////////////
createImageBitmap(blob, sxOrOptions, sy, sw, sh, options) {
if (typeof sxOrOptions === 'number') {
return createImageBitmap(blob, sxOrOptions, sy ?? 0, sw ?? 0, sh ?? 0, options);
}
else {
return createImageBitmap(blob, sxOrOptions);
}
}
getTimeStamp() {
return performance ? performance.now() : Date.now();
}
addFont(font) {
document.fonts.add(font);
}
}
//# sourceMappingURL=WebPlatform.js.map