| const lengthConv = new Map([ | |
| ['in', 96], | |
| ['px', 1], | |
| ['pt', 4 / 3], | |
| ['pc', 16], | |
| ]); | |
| const timeConv = new Map([ | |
| ['s', 1000], | |
| ['ms', 1], | |
| ]); | |
| const angleConv = new Map([ | |
| ['turn', 360], | |
| ['deg', 1], | |
| ]); | |
| /** @typedef {{time?: boolean, length?: boolean, angle?: boolean}} ConvertOptions */ | |
| /** | |
| * @param {number} number | |
| * @return {string} | |
| */ | |
| function dropLeadingZero(number) { | |
| const value = String(number); | |
| if (number % 1) { | |
| if (value[0] === '0') { | |
| return value.slice(1); | |
| } | |
| if (value[0] === '-' && value[1] === '0') { | |
| return '-' + value.slice(2); | |
| } | |
| } | |
| return value; | |
| } | |
| /** | |
| * @param {number} number | |
| * @param {string} originalUnit | |
| * @param {typeof lengthConv | typeof timeConv | typeof angleConv} conversions | |
| * @return {string} | |
| */ | |
| function transform(number, originalUnit, conversions) { | |
| const conversionUnits = [...conversions.keys()].filter((u) => { | |
| return originalUnit !== u; | |
| }); | |
| const base = number * /** @type {number} */ (conversions.get(originalUnit)); | |
| let shortest = ''; | |
| for (const u of conversionUnits) { | |
| const value = | |
| dropLeadingZero(base / /** @type {number} */ (conversions.get(u))) + u; | |
| if (!shortest || value.length < shortest.length) { | |
| shortest = value; | |
| } | |
| } | |
| return shortest; | |
| } | |
| /** | |
| * @param {number} number | |
| * @param {string} unit | |
| * @param {ConvertOptions} options | |
| * @return {string} | |
| */ | |
| const convert = function (number, unit, options) { | |
| const { time, length, angle } = options; | |
| let value = dropLeadingZero(number) + (unit ? unit : ''); | |
| let converted; | |
| const lowerCaseUnit = unit.toLowerCase(); | |
| if (length !== false && lengthConv.has(lowerCaseUnit)) { | |
| converted = transform(number, lowerCaseUnit, lengthConv); | |
| } | |
| if (time !== false && timeConv.has(lowerCaseUnit)) { | |
| converted = transform(number, lowerCaseUnit, timeConv); | |
| } | |
| if (angle !== false && angleConv.has(lowerCaseUnit)) { | |
| converted = transform(number, lowerCaseUnit, angleConv); | |
| } | |
| if (converted && converted.length < value.length) { | |
| value = converted; | |
| } | |
| return value; | |
| }; | |
| export default convert; |