another-dimension
v0.4.9
Published
A lightweight library for converting units of length
Downloads
95
Maintainers
Readme
A lightweight library for converting units of length
another-dimension
helps to convert between various units of length, with a focus on units used for screen presentation (physical screen pixels) and visual perception experiments (arcminutes, arcseconds).
Why another unit conversion library?
- Lightweight, only supporting length units, no dependencies. If you are looking for general conversion of various units, consider js-quantities, convert-units, convert or others.
- Support for angular dimensions (degrees, arcminutes and arcseconds) which depend on viewing distance and involve trigonometric calculations in the conversion.
- Support for physical screen pixels taking into account the (configurable) pixel density.
- Global configuration of pixel density and viewing distance for accurate conversion from/to physical screen pixels and angular length units, as often needed for accurate reproduction of perceptual experiments and user studies.
- Modern-style, function-based, highly configurable implementation.
- 100% test coverage.
another-dimension
was created as part of the stimsrv project to support the accurate specification of dimensions for screen-based psychological experiments.
| — In a Nutshell — | — Installation & Import — | — API Documentation — | — Supported Units — | — Credits — |
another-dimension
in a Nutshell
const Dimension = require('another-dimension');
// Simple use case: unit conversion
// Create some dimensions
let width = Dimension("10mm"); // 10 mm
let length = Dimension("1.8in"); // 1.8 inch
console.log("Metric length: " + length.toString("mm"));
// => "Metric length: 45.72mm"
// Optional: Configuration of global settings
Dimension.configure({
defaultOutputUnit: "px", // convert to pixels when value is used as Number
defaultUnit: "px", // default unit to use if no unit is specified
pixelDensity: 440, // 440ppi, pixel density of HiDPI smartphone
// (used to convert pixel sizes)
viewingDistance: 350 // 350mm viewing distance (typical for smartphone use),
// (used to convert angular dimensions)
});
// Create more dimensions
let height = Dimension(50, "arcmin"); // 50 angular minutes
let depth = Dimension(50); // 50 pixels (as per defaultUnit specified above)
// Dimension objects can be used in place of numeric primitives,
// and will implicitly be converted to pixels (as configured above per defaultOutputUnit)
// This will draw a 173.2 x 88.2 pixel rectangle!
canvasContext2D.fillRect(0, 0, width, height);
// Dimension containing the length of the diagonal in pixels (set as defaultUnit above)
let diagonal = Dimension(Math.sqrt(width ** 2 + height ** 2));
// Ouptut diagonal length in mm, using 2 digits precision
console.log("Diagonal length: " + diagonal.toString("mm",2));
// => "Diagonal length: 11.22mm"
Installation & Import
Node.js
npm install another-dimension
CommonJS require() syntax:
const Dimension = require('another-dimension');
ES module import syntax:
import Dimension from 'another-dimension';
Browser
For direct use in the browser, download the file another-dimension.js
and load it using a <script>
tag.
<script src="another-dimension.js"></script>
<script>
let dim = Dimension("1in");
console.log(dim.toString("mm")); // -> 25.4mm
</script>
By default, another-dimension is made available as a global variable named Dimension
. You can change the name of the global variable by adding an attribute data-another-dimension-global
to the script tag, specifying the global name to use for the Dimension object.
<script src="another-dimension.js" data-another-dimension-global="AnotherDimension"></script>
<script>
let dim = AnotherDimension("1in");
console.log(dim.toString("mm")); // -> 25.4mm
</script>
Note: another-dimension
works out of the box like this for prototyping in modern browsers. For compatibility with older browsers and optimized delivery consider compiling your project code, including this library, using Babel or similar tools.
API Documentation
Creating Dimensions
Dimension(spec[, options])
Can be used with new
as constructor, or without as a factory function.
let lengthA = new Dimension("12mm"); // Constructor syntax
let lengthB = Dimension("12mm"); // Factory syntax
spec
can be a Number, a String, or an Object providing a value
and optional unit
entry.
// String providing value + unit
let lengthA = Dimension("12mm");
// Object providing value and (optionally) unit
let lengthB = Dimension({value: 12, unit: "mm"});
// Number will use default unit (initially "mm")
let lengthC = Dimension(12);
options
can be a String specifying the unit, or an object with some of the following entries:
options.defaultUnit
Unit to use if not specified, overrides global default unit.
// specify value and unit separately
let lengthA = Dimension(12, "mm");
// specify defaultUnit in options
let lengthB = Dimension(12, {defaultUnit: "in"}); // => 12 inches
// specified unit takes precedence over options.defaultUnit
let lengthC = Dimension("12mm", {defaultUnit: "in"}); // => 12 mm
Retrieving and converting Dimensions
dimensionInstance.toDimension(targetUnit)
Returns a new Dimension instance, converted to the targetUnit
.
let dim = Dimension("1in");
let dimMM = dim.toDimension("mm"); // Dimension with value: 25.4 and unit: "mm"
dimensionInstance.toNumber(targetUnit)
Returns the dimension converted to targetUnit
, as a Number. If targetUnit
is not specified, return the unconverted value.
let dim = Dimension("1in");
let mm = dim.toNumber("mm"); // 25.4
let inches = dim.toNumber(); // 1
dimensionInstance.toString([targetUnit], [digits])
Returns a String representation of the dimension (e.g. "12.1mm"
).
targetUnit
Unit to convert to.
digits
Number of digits after the comma to include.
let dim = Dimension("1.8in");
let mmStr = dim.toString("mm"); // "45.72mm"
let mmRound = dim.toString("mm", 1); // "45.7mm"
let round = dim.toString(2); // "1.80in"
dimensionInstance.toFixed([digits[, targetUnit]])
Returns a String representation of the numeric value of the dimension with fixed precision (e.g. "12.1"
), similar to the JavaScript builtin `Number.toFixed().
digits
Number of digits after the comma to include. If omitted, it is considered 0, i.e. rounding to full integer.
targetUnit
Unit to convert to.
let dim = Dimension("1.8in");
let fixed = dim.toFixed(2); // "1.80"
let mmFixed = dim.toFixed(1, "mm"); // "45.7"
let round = dim.toFixed(); // "2"
dimensionInstance.toJSON()
Returns a plain JavaScript object containing entries for value
and unit
, unless configured otherwise by setting the toJSON
option with Dimension.configure()
.
dimensionInstance.valueOf()
Returns the numeric value of the dimension converted to the globally configured defaultOutputUnit
, or the unconverted value if defaultOutputUnit
has not been set.
This method is called internally by the JavaScript interpreter when a Dimension object is used in place of a primitive value, and is provided for this purpose. It should generally rarely be called explicitly (use dimensionInstance.toNumber()
, dimensionInstance.toFixed()
or dimensionInstance.toString()
for better control over the output instead).
Using Dimensions as primitives
For Objects involved in numeric calculations, the JavaScript interpreter internally calls .valueOf()
on the Object before performing the operation. By default, valueOf()
of Dimension instances returns their (unconverted) numerical value. If the global option defaultOutputUnit
is set, the value is converted to the specified unit first.
let dim = Dimension("1in");
console.log(dim + dim); // 2
Dimension.configure({
defaultOutputUnit: "mm"
});
console.log(dim + dim); // 50.8
Global Configuration
Dimension.configure(options)
Set global configuration options.
options
is an object containing global configuration options.
| Option | Default | Description |
| ----------------------- | ------- | ------------- |
| defaultUnit
| "mm"
| Default unit to use when creating Dimension instances. |
| defaultOutputUnit
| null
| Unit to convert to when a Dimension instance is used as a primitive value. null
uses the object's specified unit (so no conversion takes place). |
| anchorUnit
| "mm"
| Unit to try as intermediate unit when no direct conversion from source to target unit is available. |
| pixelDensity
| 96
| Pixel density (in pixels-per-inch) to use for converting pixel values. |
| viewingDistance
| 600
| Viewing distance (in mm) to use for converting angular dimensions. The default of 600mm is often used for "Desktop" settings, for mobile phones use 300-350mm. |
| aliases
| see Supported Units | A key-value map of unit aliases, e.g. {'"': 'in'}
to use the " character as an alias for inches. Warning: setting this here will overwrite the internal alias table. Use Dimension.addAlias()
to add aliases to the internal alias table. |
| toJSON
| see above | Function to use for .toJSON()
of Dimension instances. Takes a Dimensions object as parameter, returns its JSON representation (plain JS Object). |
| dimensionRegEx
| see below | The regular expression used to parse dimension Strings. Has to define two named groups value
and unit
, which will be used to extract the numeric value and unit specifier from the String. |
Default config.dimensionRegEx
: /^\s*(?<value>-?[0-9]*\.?[0-9]+)\s*(?<unit>[^\s\d]+)\s*$/
(This allows for padding whitespace, whitespace separating value and unit, and special characters (but no digits) in the unit specifier.)
Dimension.addConversion(fromUnit, toUnit, factorOrFunction)
Add a conversion, specified as a fixed conversion factor or a function.
fromUnit
String specifying the unit to convert from.
toUnit
String specifying the unit to convert to.
factorOrFunction
either a Number, specifying a fixed conversion factor, or a Function that will be called for each conversion with the following parameters:
value
the value to convert.config
the global configuration object (seeDimension.configure()
).
To introduce a new unit, you only need to supply a conversion to and from the anchorUnit
(by default: "mm"
) as a bare minimum.
Example:
// (these conversions are already built in and serve only for illustration purposes)
// to convert from inch to mm, multiply with 25.4
Dimension.addConversion("in", "mm", 25.4);
// to convert from inches to pixels, multiply with config.pixelDensity
Dimension.addConversion("in", "px", (v, config) => v * config.pixelDensity);
Dimension.addAlias(unit, alias)
Add an alias (alternative name) for a unit. The aliases will be considered before any conversion. Warning: Aliases are not looked up recursively, so each alias has to refer to a unit which is actually specified (i.e. for which conversions are either built in or have been specified using Dimension.addConversion()
).
unit
A String specifying the base unit.
alias
A String or an Array of Strings, specifying alias name(s).
Example:
// " is not configured as an alias for inches by default, as it may be confused with arcseconds.
// to use " as an alias for inches
Dimension.addAlias("in", '"');
let length = Dimension('12"');
console.log(length.toString());
// => 12in
Global Helpers
Dimension.getConversionFunction(fromUnit, toUnit[, options])
Return a specific conversion function. The returned function will accept a single parameter - the value to convert - and will return the converted value.
fromUnit
String specifying the unit to convert from.
toUnit
String specifying the unit to convert to.
options
Object with some of the following entries:
options.freezeConfig
: If set to true, the current configuration (e.g. pixelDensity, viewingDistance) will be "frozen", so that subsequent changes to those parameters won't affect the conversion function. If not set (the default), changes to the global configuration will affect the conversion performed by the returned function, if applicable.
let conv = Dimension.getConversionFunction("in", "mm");
let mm = conv(1); // 25.4
Dimension.unAlias(unit)
Returns the canonical unit referenced by the given alias, or the unit passed in if no such alias is defined.
let unit = Dimension.unAlias("°");
console.log(unit);
// => "deg"
Dimension.parseDimensionString(dimensionString)
Parses a String into a plain JS object containing entries for value
and unit
, using the built-in or configured dimensionRegEx
regular expression.
If the String contains no unit but a number, the defaultUnit
is used as unit.
If neither dimensionRegEx
nor number match, the function returns null.
Dimension.getUnits()
Returns an Array containing all currently configured Dimensions (without aliases).
Supported Units
The list of built-in units is deliberately kept short. New units can be added quickly by providing conversion functions or factors (at minimum to and from the global base unit config.anchorUnit
) using Dimension.addConversion()
Metric Units
| Unit / Aliases | Description | mm |
| -------------- | ----------- | ---- |
| km
| Kilometer | 10^6 |
| m
| Meter | 10^3 |
| cm
| Centimeter | 10 |
| mm
| Millimeter | 1 |
| µ
/ µm
/ um
| Micrometer | 10^-3 |
Imperial Units
| Unit / Aliases | Description | mm |
| -------------- | ----------- | ---- |
| in
| Inch | 25.4 |
| thou
| Thousandths of an Inch | 0.0254 |
Typesetting Units
| Unit / Aliases | Description | mm |
| -------------- | ----------- | ---- |
| pc
| (DTP) Pica (1/6in) | ≈4.23 |
| pt
| (DTP) Point (1/12pc) | ≈0.353 |
| twip
| Twip (1/20pt) | ≈0.0176 |
Screen Units
| Unit / Aliases | Description | mm |
| -------------- | ----------------------- | ---- |
| px
| Physical Screen Pixel | Varying, depending on config.pixelDensity
(≈0.265mm @ 96dpi)|
Angular Units
| Unit / Aliases | Description | mm |
| -------------- | ----------- | ---- |
| deg
/ °
| Angular Degree | Varying, depending on config.viewingDistance
(≈10.5mm @ 600mm) |
| arcmin
| Arc Minute | Varying, depending on config.viewingDistance
(≈0.175mm @ 600mm) |
| arcsec
| Arc Second | Varying, depending on config.viewingDistance
(≈0.003mm @ 600mm)|
Test coverage report
File | % Stmts | % Branch | % Funcs | % Lines ----------------------|---------|----------|---------|--------- another-dimension.js | 100 | 100 | 100 | 100
Credits
another-dimension
was created by Florian Ledermann as part of the stimsrv project.
License: MIT License.
"I'll take your brains to another dimension ... pay close attention!" — In memoriam Keith Flint / The Prodigy