Skip to content

DPI / PPI Calculator — JavaScript source

Compute screen pixel density (PPI/DPI), dot pitch, physical dimensions, and aspect ratio from any resolution. Solve for PPI from a diagonal, or derive the diagonal from a known PPI - all in your browser.

This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.

// Display pixel-density math (JavaScript port).
//
// Pure, deterministic, never throws. Non-positive inputs that would cause
// division by zero produce NaN or Infinity (standard IEEE-754 behavior)
// rather than throwing - callers should guard with Number.isFinite before
// display.
//
// CosmoDev polyglot showcase port of `dpi-ppi`, ported from
// src/lib/dpi-ppi.ts. Display source - part of CosmoDev's polyglot tool pages.

const MM_PER_INCH = 25.4;

/**
 * Diagonal length in pixels: √(w² + h²).
 * The sign of the inputs is irrelevant because both terms are squared.
 */
export function diagonalPixels(w, h) {
  return Math.sqrt(w * w + h * h);
}

/**
 * Pixels per inch, given a resolution and a known physical diagonal (inches).
 */
export function computePpi({ w, h, diagonalInches }) {
  return { ppi: diagonalPixels(w, h) / diagonalInches };
}

/**
 * Physical dimensions from a resolution and a ppi. Returns inches and
 * millimeters for width, height, and diagonal.
 */
export function physicalSize({ w, h, ppi }) {
  const widthIn = w / ppi;
  const heightIn = h / ppi;
  return {
    widthIn,
    heightIn,
    diagonalIn: diagonalPixels(widthIn, heightIn),
    widthMm: widthIn * MM_PER_INCH,
    heightMm: heightIn * MM_PER_INCH,
  };
}

/**
 * Dot pitch (pixel size) in millimeters per pixel: 25.4 / ppi.
 */
export function dotPitch(ppi) {
  return MM_PER_INCH / ppi;
}

/**
 * Integer greatest-common-divisor via Euclid's algorithm, used to reduce
 * aspect ratios. Inputs are truncated toward zero and taken in absolute
 * value first, so the sign and fractional part of the inputs never matter.
 */
function gcd(a, b) {
  let x = Math.abs(Math.trunc(a));
  let y = Math.abs(Math.trunc(b));
  while (y !== 0) {
    const t = y;
    y = x % y;
    x = t;
  }
  return x;
}

/**
 * Reduced aspect ratio as "w:h" (e.g. "16:9").
 * Returns "-" when either side is not a positive number (this also covers
 * NaN, since every comparison with NaN is false).
 */
export function aspectRatio(w, h) {
  if (!(w > 0) || !(h > 0)) return '-';
  const g = gcd(w, h);
  if (g === 0) return '-';
  return `${Math.trunc(w) / g}:${Math.trunc(h) / g}`;
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →