import FrameRateMeasuredEvent from "./events/FrameRateMeasuredEvent.js"; export default class FrameRateMeasurer { constructor(rounds = 30) { this.rounds = rounds; this.round = 0; this.lastTimestamp = undefined; this.frameDurations = []; window.requestAnimationFrame( (timestamp) => { this.measureFrameRate(timestamp); } ); } measureFrameRate(timestamp) { if (this.lastTimestamp !== undefined) { this.round++; this.frameDurations.push(timestamp - this.lastTimestamp); this.lastTimestamp = timestamp; if (this.round < this.rounds) { window.requestAnimationFrame( (timestamp) => { this.measureFrameRate(timestamp); } ); } else { window.dispatchEvent(new FrameRateMeasuredEvent(this.getAverageFrameRate())); } } else { this.round = 0; this.lastTimestamp = timestamp; window.requestAnimationFrame( (timestamp) => { this.measureFrameRate(timestamp); } ); } this.lastTimestamp = timestamp } getAverageFrameRate() { let frameDurationSum = 0; this.frameDurations.forEach( (duration) => { frameDurationSum += duration; } ); let durationAverage = frameDurationSum / this.frameDurations.length; return 1000 / durationAverage; } getFrameRate() { const DEFAULT_FRAME_RATES = [30, 60, 120]; let averageFrameRate = this.getAverageFrameRate(); let closestDistance = {frameRate: 0, distance: 99999}; DEFAULT_FRAME_RATES.forEach( (frameRate) => { let distance = Math.abs(frameRate - averageFrameRate); if (closestDistance.distance > distance) { closestDistance.frameRate = frameRate; closestDistance.distance = distance; } } ); console.log(this.frameDurations); return closestDistance.frameRate; } }