/** * Copyright schukai GmbH and contributors 2023. All Rights Reserved. * Node module: @schukai/monster * This file is licensed under the AGPLv3 License. * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html */ import { getWindow } from "./util.mjs"; export { convertToPixels, getDeviceDPI }; /** * Stores the DPI of the device. * * @private * @returns {number} * @since 3.34.0 * @type {number|function} */ let CURRENT_DEVICE_DPI = function () { let i = 0; for (i = 56; i < 2000; i++) { if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) { return i; } } return i; }; /** * Returns the DPI of the device. * * @since 3.34.0 * @memberOf Monster.DOM * @returns {number} */ function getDeviceDPI() { // only call the function once if (typeof CURRENT_DEVICE_DPI === "function") { CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI(); } return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI; } /** * Converts a CSS value to pixels. * * As Example: * * ```js * convertToPixels('1em') // returns the current font size in pixels * convertToPixels('1rem') // returns the current root font size in pixels * convertToPixels('1px') // returns 1 * convertToPixels('100%') // returns the current width of the parent element in pixels * ``` * * Following units are supported: * - px * - em * - rem * - % * * @param {string} value * @param {HTMLElement} [parentElement=document.documentElement] * @param {HTMLElement} [fontSizeElement=document.documentElement] * @returns {number} * @license AGPLv3 * @since 3.34.0 * @copyright schukai GmbH * @throws {Error} Unsupported unit * @memberOf Monster.DOM * @throws {Error} Invalid value format */ function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) { const regex = /^([\d.]+)(.*)$/; const matchResult = value.match(regex); if (!matchResult) { throw new Error(`Invalid value format: ${value}`); } const [, num, unit] = matchResult; const number = parseFloat(num); const dpi = getDeviceDPI(); if (unit === "px") { return number; } else if (unit === "em") { const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize); return number * fontSize; } else if (unit === "rem") { const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize); return number * rootFontSize; } else if (unit === "%") { const parentWidth = parseFloat(window.getComputedStyle(parentElement).width); return (number * parentWidth) / 100; } else if (unit === "in") { return number * dpi; } else if (unit === "cm") { return (number * dpi) / 2.54; } else if (unit === "mm") { return (number * dpi) / 25.4; } else if (unit === "pt") { return (number * dpi) / 72; } else if (unit === "pc") { return (number * dpi) / 6; } else { throw new Error(`Unsupported unit: ${unit}`); } }