UNPKG

screencalc

Version:

Calculate data about any display (width, height, ratio, area, density, etc.)

324 lines (323 loc) 14 kB
"use strict"; exports.__esModule = true; var ScreenMath = require("./ScreenMath"); /** * Allows screen information to be easily stored and calculated */ var ScreenCalc = (function () { function ScreenCalc(properties) { // properties should be initialized to null this.d = { pixelWidth: null, pixelHeight: null, pixelCount: null, pixelDensity: null, ratio: null, physicalWidth: null, physicalHeight: null, area: null, diagonalSize: null }; var intProps = { pixelWidth: true, pixelHeight: true, pixelCount: true }; for (var property in properties) { var prop = property; if (intProps[prop] && !ScreenMath.isPositiveInt(properties[prop])) { throw new Error(prop + " must be a positive integer"); } else if (!ScreenMath.isPositiveNum(properties[prop])) { throw new Error(prop + " must be a positive number"); } this.d[prop] = properties[prop]; } } /** * Attempts to calculate/return the pixel height of the screen. */ ScreenCalc.prototype.getPixelHeight = function () { if (this.d.physicalHeight !== null && this.d.pixelDensity !== null) { return this.d.physicalHeight * this.d.pixelDensity; } try { var ratio = this.getRatio(); if (this.d.pixelWidth !== null) { return this.d.pixelWidth / ratio; } else if (this.d.pixelCount !== null) { return ScreenMath.heightFromRatioAndArea(ratio, this.d.pixelCount); } else if (this.d.diagonalSize !== null && this.d.pixelDensity !== null) { var physicalHeight = ScreenMath.physicalHeightFromRatioAndDiagonalSize(ratio, this.d.diagonalSize); return physicalHeight * this.d.pixelDensity; } else if (this.d.area !== null && this.d.pixelDensity !== null) { var physicalHeight = ScreenMath.heightFromRatioAndArea(ratio, this.d.area); return physicalHeight * this.d.pixelDensity; } } catch (e) { } if (this.d.pixelHeight === null) { throw new Error("Insufficient data to calculate pixel height"); } return this.d.pixelHeight; }; /** * Attempts to calculate/return the pixel width of the screen. */ ScreenCalc.prototype.getPixelWidth = function () { if (this.d.physicalWidth !== null && this.d.pixelDensity !== null) { return this.d.physicalWidth * this.d.pixelDensity; } try { return this.getPixelHeight() * this.getRatio(); } catch (e) { } if (this.d.pixelWidth === null) { throw new Error("Insufficient data to calculate pixel width"); } return this.d.pixelWidth; }; /** * Attempts to calculate/return the screen's physical height. */ ScreenCalc.prototype.getPhysicalHeight = function () { try { var pixelHeight = this.getPixelHeight(); if (this.d.pixelDensity !== null) { return pixelHeight / this.d.pixelDensity; } } catch (e) { } try { var ratio = this.getRatio(); if (this.d.physicalWidth !== null) { return this.d.physicalWidth / ratio; } else if (this.d.diagonalSize !== null) { return ScreenMath.physicalHeightFromRatioAndDiagonalSize(ratio, this.d.diagonalSize); } else if (this.d.area !== null) { return ScreenMath.heightFromRatioAndArea(ratio, this.d.area); } } catch (e) { } if (this.d.physicalHeight === null) { throw new Error("Insufficient data to calculate physical height"); } return this.d.physicalHeight; }; /** * Attempts to calculate/return the screen's physical width. */ ScreenCalc.prototype.getPhysicalWidth = function () { if (this.d.pixelDensity !== null && this.d.pixelWidth !== null) { return this.d.pixelWidth / this.d.pixelDensity; } try { return this.getPhysicalHeight() * this.getRatio(); } catch (e) { } if (this.d.physicalWidth === null) { throw new Error("Insufficient data to calculate physical width"); } return this.d.physicalWidth; }; /** * Attempts to calculate/return the screen's diagonal size. */ ScreenCalc.prototype.getDiagonalSize = function () { try { var w = this.getPhysicalWidth(); var h = this.getPhysicalHeight(); var diagonalSq = (h * h) + (w * w); return Math.sqrt(diagonalSq); } catch (e) { } if (this.d.diagonalSize === null) { throw new Error("Insufficient data to calculate diagonal size"); } return this.d.diagonalSize; }; /** * Returns the number of pixels per unit in the display * (will be ppi if units are in, or ppcm if units are cm) */ ScreenCalc.prototype.getPixelDensity = function () { try { return this.getPixelHeight() / this.getPhysicalHeight(); } catch (e) { } try { return this.getPixelWidth() / this.getPhysicalWidth(); } catch (e) { } if (this.d.pixelDensity === null) { throw new Error("Insufficient data to calculate pixel density"); } return this.d.pixelDensity; }; /** * Returns the area of the display in square units. */ ScreenCalc.prototype.getArea = function () { try { return this.getPhysicalWidth() * this.getPhysicalHeight(); } catch (e) { } if (this.d.area === null) { throw new Error("Insufficient data to calculate area"); } return this.d.area; }; /** * Returns the total number of pixels in the screen. */ ScreenCalc.prototype.getPixelCount = function () { try { return this.getPixelWidth() * this.getPixelHeight(); } catch (e) { } if (this.d.pixelCount === null) { throw new Error("Insufficient data to calculate pixel count"); } return this.d.pixelCount; }; /** * Returns the screen's width divided by its height. * For example, the ratio of a 1920x1080 display would * be 1.78 when rounded to two decimal places. */ ScreenCalc.prototype.getRatio = function () { // try to calculate the ratio from width and height if possible var wAndH = this.calculateWidthAndHeight(); if (wAndH !== null) { return wAndH.width / wAndH.height; } if (this.d.ratio === null) { throw new Error("Insufficient data to calculate ratio"); } return this.d.ratio; }; /** * Returns an object with 'width' and 'height' properties containing a simplified ratio for the display. * Additionally, a 'difference' property is included which contains the difference between the simplified * and original ratio (0 if the simplified ratio is exact). For example, a 1366x768 display would (by default) * return { width: 16, height: 9, difference: -0.0008680555555555802 }. * Returns null if there is not enough data to calculate the ratio. * @param precision (optional) pass a number between 0 and 1 for precision (defaults to 5.0e-3). * The closer the number is to zero the greater the precision. For example, if 1.0e-6 is passed, * the return value for a 1366x768 display would be { width: 683, height: 384, difference: 0 }. */ ScreenCalc.prototype.getSimpleRatio = function (precision) { var ratio = this.getRatio(); var fractionArr = ScreenMath.calculateSimplestFraction(ratio, precision); var simpleWidth = fractionArr[0]; var simpleHeight = fractionArr[1]; // 8:5 ratios should be converted to 16:10 if (simpleWidth / simpleHeight === 16 / 10) { simpleWidth = 16; simpleHeight = 10; } else if (simpleWidth / simpleHeight === 10 / 16) { simpleWidth = 10; simpleHeight = 16; } var difference = (simpleWidth / simpleHeight) - ratio; return { width: simpleWidth, height: simpleHeight, difference: difference }; }; /** * Returns the same simplified ratio as getSimpleRatio(), but as a string in the format width:height. * For example, a 1920x1080 display would return "16:9". If the ratio is imprecise, a tilde (~) character * is prepended to the string (i.e. "~16x9"). * Returns null if there is not enough data to calculate the ratio. * @param precision (optional) pass a number between 0 and 1 for precision (defaults to 5.0e-3). * The closer the number is to zero the greater the precision. For example, if 1.0e-6 is passed, * the return value for a 1366x768 display would be the precise ratio "683:384". */ ScreenCalc.prototype.getStringRatio = function (precision) { var ratio = this.getSimpleRatio(precision); var strRatio = ratio.width.toString() + ':' + ratio.height.toString(); if (ratio.difference !== 0) { strRatio = "~" + strRatio; } return strRatio; }; /** * Tries to calculate width and height in the same units (used for ratio calculation). * Returns an object with height and width properties, or null if insufficient data. */ ScreenCalc.prototype.calculateWidthAndHeight = function () { if (this.d.pixelWidth !== null && this.d.pixelHeight !== null) { return { width: this.d.pixelWidth, height: this.d.pixelHeight }; } else if (this.d.physicalWidth !== null && this.d.physicalHeight !== null) { return { width: this.d.physicalWidth, height: this.d.physicalHeight }; } if (this.d.pixelDensity !== null) { if (this.d.pixelWidth !== null && this.d.physicalHeight !== null) { var physicalWidth = this.d.pixelWidth / this.d.pixelDensity; return { width: physicalWidth, height: this.d.physicalHeight }; } else if (this.d.pixelHeight !== null && this.d.physicalWidth !== null) { var physicalHeight = this.d.pixelHeight / this.d.pixelDensity; return { width: this.d.physicalWidth, height: physicalHeight }; } else if (this.d.pixelHeight !== null && this.d.diagonalSize !== null) { var physicalHeight = this.d.pixelHeight / this.d.pixelDensity; var physicalWidth = Math.sqrt(Math.pow(this.d.diagonalSize, 2) - Math.pow(physicalHeight, 2)); return { width: physicalWidth, height: physicalHeight }; } else if (this.d.pixelWidth !== null && this.d.diagonalSize !== null) { var physicalWidth = this.d.pixelWidth / this.d.pixelDensity; var physicalHeight = Math.sqrt(Math.pow(this.d.diagonalSize, 2) - Math.pow(physicalWidth, 2)); return { width: physicalWidth, height: physicalHeight }; } } if (this.d.pixelCount !== null) { if (this.d.pixelHeight !== null) { return { width: this.d.pixelCount / this.d.pixelHeight, height: this.d.pixelHeight }; } else if (this.d.pixelWidth !== null) { return { width: this.d.pixelWidth, height: this.d.pixelCount / this.d.pixelWidth }; } else if (this.d.pixelDensity !== null) { if (this.d.physicalHeight !== null) { var pixelHeight = this.d.physicalHeight * this.d.pixelDensity; return { width: this.d.pixelCount / pixelHeight, height: pixelHeight }; } else if (this.d.physicalWidth !== null) { var pixelWidth = this.d.physicalWidth * this.d.pixelDensity; return { width: pixelWidth, height: this.d.pixelCount / pixelWidth }; } } } if (this.d.diagonalSize !== null) { // Pythagorean theorem: width squared + height squared = diagonal squared var diagonalSq = Math.pow(this.d.diagonalSize, 2); if (this.d.physicalWidth !== null) { var widthSq = Math.pow(this.d.physicalWidth, 2); var heightSq = diagonalSq - widthSq; return { width: this.d.physicalWidth, height: Math.sqrt(heightSq) }; } else if (this.d.physicalHeight !== null) { var heightSq = Math.pow(this.d.physicalHeight, 2); var widthSq = diagonalSq - heightSq; return { width: Math.sqrt(widthSq), height: this.d.physicalHeight }; } } if (this.d.area !== null) { if (this.d.physicalHeight !== null) { return { width: this.d.area / this.d.physicalHeight, height: this.d.physicalHeight }; } else if (this.d.physicalWidth !== null) { return { width: this.d.physicalWidth, height: this.d.area / this.d.physicalWidth }; } } return null; }; return ScreenCalc; }()); exports["default"] = ScreenCalc;