UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

131 lines (119 loc) 3.42 kB
/** * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved. * Node module: @schukai/monster * * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3). * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html * * For those who do not wish to adhere to the AGPLv3, a commercial license is available. * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms. * For more information about purchasing a commercial license, please contact schukai GmbH. * * SPDX-License-Identifier: AGPL-3.0 */ import { getWindow } from "./util.mjs"; import { validateString } from "../types/validate.mjs"; export { convertToPixels, getDeviceDPI }; /** * Stores the DPI of the device. * * @private * @return {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 * @return {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] * @return {number} * @license AGPLv3 * @since 3.34.0 * @copyright schukai GmbH * @throws {Error} Unsupported unit * @throws {Error} Invalid value format */ function convertToPixels( value, parentElement = document.documentElement, fontSizeElement = document.documentElement, ) { validateString(value); 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}`); } }