UNPKG

kinetic-slider

Version:

A WebGL-powered kinetic slider component using PIXI.js

217 lines (215 loc) 7.2 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var ThrottleStrategy = /* @__PURE__ */ ((ThrottleStrategy2) => { ThrottleStrategy2["FIXED_FPS"] = "fixed_fps"; ThrottleStrategy2["ADAPTIVE"] = "adaptive"; ThrottleStrategy2["PRIORITY"] = "priority"; ThrottleStrategy2["NONE"] = "none"; return ThrottleStrategy2; })(ThrottleStrategy || {}); const DEFAULT_CONFIG = { targetFps: 60, minFps: 30, maxFps: 120, strategy: "fixed_fps" /* FIXED_FPS */, enableMonitoring: true }; class FrameThrottler { /** * Create a new FrameThrottler with the specified configuration. * * @param {ThrottlerConfig} [config] - Configuration options for the throttler * * @example * // Create a throttler with default settings (60fps, FIXED_FPS strategy) * const throttler = new FrameThrottler(); * * @example * // Create a throttler with custom settings * const throttler = new FrameThrottler({ * targetFps: 30, * strategy: ThrottleStrategy.ADAPTIVE, * minFps: 15, * maxFps: 60 * }); */ constructor(config) { /** Active configuration */ __publicField(this, "config"); /** Performance monitoring data */ __publicField(this, "performance"); /** Timestamp of the last processed frame */ __publicField(this, "lastFrameTime", 0); this.config = { ...DEFAULT_CONFIG, ...config }; this.performance = { frameTimes: [], currentFps: this.config.targetFps, frameCount: 0, lastAdjustment: performance.now(), currentInterval: this.calculateInterval(this.config.targetFps) }; this.lastFrameTime = performance.now(); } /** * Calculate the frame interval in milliseconds from FPS. * * @param {number} fps - Frames per second * @returns {number} Interval in milliseconds between frames * @private */ calculateInterval(fps) { return 1e3 / fps; } /** * Check if enough time has passed to process the next frame. * * @param {number} [priority] - Optional priority level to consider (higher values bypass more throttling) * @returns {boolean} True if the frame should be processed, false if it should be skipped * * @example * // Basic usage in animation loop * if (throttler.shouldProcessFrame()) { * // Process frame * render(); * throttler.frameProcessed(); * } * * @example * // Usage with priority (3 is highest priority) * if (throttler.shouldProcessFrame(2)) { * // Process high-priority frame * renderImportantElements(); * throttler.frameProcessed(); * } */ shouldProcessFrame(priority) { const now = performance.now(); const elapsed = now - this.lastFrameTime; switch (this.config.strategy) { case "none" /* NONE */: return true; case "priority" /* PRIORITY */: if (priority !== void 0 && priority >= 2) { return true; } return elapsed >= this.performance.currentInterval; case "adaptive" /* ADAPTIVE */: this.updateAdaptivePerformance(now); return elapsed >= this.performance.currentInterval; case "fixed_fps" /* FIXED_FPS */: default: return elapsed >= this.performance.currentInterval; } } /** * Mark the current frame as processed and update timing metrics. * Should be called after processing a frame that passed the shouldProcessFrame check. * * @example * if (throttler.shouldProcessFrame()) { * // Process frame * render(); * throttler.frameProcessed(); * } */ frameProcessed() { const now = performance.now(); const frameDuration = now - this.lastFrameTime; this.lastFrameTime = now; if (this.config.enableMonitoring) { this.updatePerformanceMetrics(frameDuration); } } /** * Update performance metrics with the latest frame duration. * * @param {number} frameDuration - Duration of the last frame in milliseconds * @private */ updatePerformanceMetrics(frameDuration) { this.performance.frameTimes.push(frameDuration); if (this.performance.frameTimes.length > 60) { this.performance.frameTimes.shift(); } const avgFrameDuration = this.performance.frameTimes.reduce((sum, time) => sum + time, 0) / this.performance.frameTimes.length; this.performance.currentFps = 1e3 / avgFrameDuration; this.performance.frameCount++; } /** * Update adaptive performance settings based on recent metrics. * This method adjusts the frame rate based on the device's capabilities. * * @param {number} now - Current timestamp in milliseconds * @private */ updateAdaptivePerformance(now) { if (now - this.performance.lastAdjustment < 1e3 || this.performance.frameTimes.length < 10) { return; } const avgFps = this.performance.currentFps; let targetFps = this.config.targetFps; if (avgFps < this.config.minFps) { targetFps = Math.max(this.config.minFps, targetFps * 0.8); } else if (avgFps > this.config.maxFps) { targetFps = Math.min(this.config.maxFps, targetFps * 1.2); } else if (avgFps > targetFps * 1.2) { targetFps = Math.min(this.config.maxFps, targetFps * 1.1); } this.performance.currentInterval = this.calculateInterval(targetFps); this.performance.lastAdjustment = now; } /** * Set a specific throttling strategy. * * @param {ThrottleStrategy} strategy - The throttling strategy to use * * @example * // Switch to adaptive strategy based on device capability * if (isLowEndDevice) { * throttler.setStrategy(ThrottleStrategy.ADAPTIVE); * } */ setStrategy(strategy) { this.config.strategy = strategy; } /** * Set a specific target FPS. * * @param {number} fps - Target frames per second (must be > 0) * * @example * // Reduce target FPS to save battery * if (isBatteryLow) { * throttler.setTargetFps(30); * } else { * throttler.setTargetFps(60); * } */ setTargetFps(fps) { this.config.targetFps = Math.max(1, fps); if (this.config.strategy === "fixed_fps" /* FIXED_FPS */) { this.performance.currentInterval = this.calculateInterval(this.config.targetFps); } } /** * Get current performance metrics for monitoring and debugging. * * @returns {Object} Performance information including current FPS, interval, frame count, and strategy * * @example * // Log performance metrics * console.log(throttler.getPerformanceMetrics()); * // Example output: { currentFps: 58.2, targetInterval: 16.67, frameCount: 1242, strategy: 'fixed_fps' } */ getPerformanceMetrics() { return { currentFps: this.performance.currentFps, targetInterval: this.performance.currentInterval, frameCount: this.performance.frameCount, strategy: this.config.strategy }; } } export { FrameThrottler, ThrottleStrategy }; //# sourceMappingURL=FrameThrottler.js.map