settings-helper.js (1644B)
1 function createSettingsDicts(width, height, step = 1) { 2 const settingsDicts = [], aspect = width / height; 3 do { 4 settingsDicts.push({ width, height }); 5 if (width > height) { 6 height = Math.round((width - step) / aspect); 7 width -= step; 8 } else { 9 width = Math.round((height - step) * aspect); 10 height -= step; 11 } 12 } while (width > 2 && height > 2); 13 return settingsDicts; 14 } 15 16 function integerFitness(actual, ideal) { 17 if (actual == ideal) { 18 return 0; 19 } 20 return Math.abs(actual - ideal) / Math.max(Math.abs(actual), Math.abs(ideal)); 21 } 22 23 function findFittestResolutionSetting(width, height, constraints) { 24 const widthIsNumber = typeof constraints.width == "number"; 25 const heightIsNumber = typeof constraints.height == "number"; 26 const c = { 27 width: { 28 ideal: widthIsNumber ? constraints.width : constraints?.width?.ideal, 29 max: constraints?.width?.max ?? 1000000, 30 }, 31 height: { 32 ideal: heightIsNumber ? constraints.height : constraints?.height?.ideal, 33 max: constraints?.height?.max ?? 1000000, 34 }, 35 }; 36 const dicts = createSettingsDicts(width, height) 37 .filter(s => s.width <= c.width.max && s.height <= c.height.max); 38 for (const dict of dicts) { 39 dict.distance = 40 integerFitness(dict.width, c.width.ideal) + 41 integerFitness(dict.height, c.height.ideal); 42 } 43 44 const filteredDicts = dicts.filter(s => { 45 return (!c.width.ideal || s.width <= c.width.ideal) && 46 (!c.height.ideal || s.height <= c.height.ideal); 47 }); 48 49 return filteredDicts.reduce( 50 (a, b) => (a.distance < b.distance ? a : b), 51 filteredDicts[0], 52 ); 53 }