From ffcae125ef3ca3a5e7f4bff809a4a7dd4f2654bb Mon Sep 17 00:00:00 2001 From: Ian Mackenzie Date: Tue, 31 Mar 2020 19:33:47 -0400 Subject: [PATCH] Add CSS and typography units to Length module Allows for some cool use cases of mixing on-screen and real-world units (like rendering physically-based 3D scenes primarily with pixel-based dimensions) --- src/Constants.elm | 18 +++++++++++++ src/Length.elm | 68 +++++++++++++++++++++++++++++++++++++++++++++++ tests/Tests.elm | 12 +++++++++ 3 files changed, 98 insertions(+) diff --git a/src/Constants.elm b/src/Constants.elm index 0ccceae..e851962 100644 --- a/src/Constants.elm +++ b/src/Constants.elm @@ -1,6 +1,7 @@ module Constants exposing ( acre , bushel + , cssPixel , cubicFoot , cubicInch , cubicMeter @@ -19,6 +20,8 @@ module Constants exposing , mole , ounce , peck + , pica + , point , pound , squareFoot , squareInch @@ -70,6 +73,21 @@ mile = 5280 * foot +cssPixel : Float +cssPixel = + inch / 96 + + +point : Float +point = + inch / 72 + + +pica : Float +pica = + inch / 6 + + ---------- UNITS OF AREA (in squared meters) ---------- diff --git a/src/Length.elm b/src/Length.elm index 870f5a4..fb55e08 100644 --- a/src/Length.elm +++ b/src/Length.elm @@ -3,6 +3,7 @@ module Length exposing , meters, inMeters , microns, inMicrons, millimeters, inMillimeters, centimeters, inCentimeters, kilometers, inKilometers , thou, inThou, inches, inInches, feet, inFeet, yards, inYards, miles, inMiles + , cssPixels, inCssPixels, points, inPoints, picas, inPicas , astronomicalUnits, inAstronomicalUnits, parsecs, inParsecs, lightYears, inLightYears , meter, micron, millimeter, centimeter, kilometer , inch, foot, yard, mile @@ -26,6 +27,11 @@ is stored as a number of meters. @docs thou, inThou, inches, inInches, feet, inFeet, yards, inYards, miles, inMiles +## CSS and typography + +@docs cssPixels, inCssPixels, points, inPoints, picas, inPicas + + ## Astronomical @docs astronomicalUnits, inAstronomicalUnits, parsecs, inParsecs, lightYears, inLightYears @@ -224,6 +230,68 @@ inMiles length = inMeters length / Constants.mile +{-| Construct a length from a number of [CSS pixels](https://drafts.csswg.org/css-values-3/#absolute-lengths), +defined as 1/96 of an inch. + +Note the difference between this function and [`Pixels.pixels`](Pixels#pixels). +`Length.cssPixels 1` is equivalent to `Length.inches (1 / 96)` or +approximately `Length.millimeters 0.264583`; it returns a length in _real world_ +units equal to the (nominal) physical size of one CSS pixel. + +In contrast, `Pixels.pixels 1` simply returns an abstract "1 pixel" value. You +can think of `Length.cssPixels 1` as a shorthand for + + Pixels.pixels 1 + |> Quantity.at_ + (Pixels.pixels 96 + |> Quantity.per (Length.inches 1) + ) + +That is, `Length.cssPixels 1` is the size of 1 pixel at a resolution of 96 DPI. + +-} +cssPixels : Float -> Length +cssPixels numCssPixels = + meters (Constants.cssPixel * numCssPixels) + + +{-| Convert a length to a number of CSS pixels. +-} +inCssPixels : Length -> Float +inCssPixels length = + inMeters length / Constants.cssPixel + + +{-| Construct a length from a number of [points](https://en.wikipedia.org/wiki/Point_%28typography%29), +defined as 1/72 of an inch. +-} +points : Float -> Length +points numPoints = + meters (Constants.point * numPoints) + + +{-| Convert a length to a number of points. +-} +inPoints : Length -> Float +inPoints length = + inMeters length / Constants.point + + +{-| Construct a length from a number of [picas](https://en.wikipedia.org/wiki/Pica_%28typography%29), +defined as 1/6 of an inch. +-} +picas : Float -> Length +picas numPicas = + meters (Constants.pica * numPicas) + + +{-| Convert a length to a number of picas. +-} +inPicas : Length -> Float +inPicas length = + inMeters length / Constants.pica + + {-| Construct a length from a number of [astronomical units][au] (AU). One AU is approximately equal to the average distance of the Earth from the Sun. diff --git a/tests/Tests.elm b/tests/Tests.elm index db68d2f..14150ab 100644 --- a/tests/Tests.elm +++ b/tests/Tests.elm @@ -124,6 +124,15 @@ lengths = , ( meters 1 , microns 1.0e6 ) + , ( cssPixels 1 + , inches (1 / 96) + ) + , ( points 1 + , inches (1 / 72) + ) + , ( picas 1 + , inches (1 / 6) + ) ] @@ -533,6 +542,9 @@ conversionsToQuantityAndBack = , fuzzFloatToQuantityAndBack "astronomicalUnits" Length.astronomicalUnits Length.inAstronomicalUnits , fuzzFloatToQuantityAndBack "parsecs" Length.parsecs Length.inParsecs , fuzzFloatToQuantityAndBack "lightYears" Length.lightYears Length.inLightYears + , fuzzFloatToQuantityAndBack "cssPixels" Length.cssPixels Length.inCssPixels + , fuzzFloatToQuantityAndBack "points" Length.points Length.inPoints + , fuzzFloatToQuantityAndBack "picas" Length.picas Length.inPicas ] , Test.describe "Mass" <| [ fuzzFloatToQuantityAndBack "kilograms" Mass.kilograms Mass.inKilograms