Skip to content

Commit bd2ce00

Browse files
Merge pull request #4 from dy/parse-number
Parse number
2 parents 14afb29 + 253c788 commit bd2ce00

File tree

5 files changed

+98
-20
lines changed

5 files changed

+98
-20
lines changed

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Get the scale factor to convert any CSS unit to `px` (logical pixel units).
99
```javascript
1010
var toPX = require('to-px')
1111

12-
console.log(toPX('em'))
13-
console.log(toPX('vh'))
12+
console.log(toPX('1em'))
13+
console.log(toPX('.23vh'))
1414
console.log(toPX('in'))
1515
```
1616

@@ -25,14 +25,15 @@ npm i to-px
2525
# API
2626

2727
#### `var scaleFactor = require('to-px')(unit[, element])`
28-
Computes the number of pixels in the unit `unit`.
2928

30-
* `unit` is a CSS unit type
29+
Computes the number of pixels in the `unit` string.
30+
31+
* `unit` is a CSS unit type or a number followed by CSS unit, eg `vh` or `2in`
3132
* `element` is an optional element in which the unit is computed (default is `document.body`)
3233

33-
**Returns** The number of pixels in one `unit`
34+
**Returns** The number of pixels in the `unit`
3435

3536
**Note** Conversions for `%` are not supported since they are context dependent.
3637

3738
# License
38-
(c) 2015 Mikola Lysenko. MIT License
39+
(c) 2015 Mikola Lysenko. MIT License

topx.js renamed to browser.js

+21-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ var parseUnit = require('parse-unit')
44

55
module.exports = toPX
66

7-
var PIXELS_PER_INCH = 96
7+
var PIXELS_PER_INCH = getSizeBrutal('in', document.body) // 96
8+
89

910
function getPropertyInPX(element, prop) {
1011
var parts = parseUnit(getComputedStyle(element).getPropertyValue(prop))
@@ -14,19 +15,22 @@ function getPropertyInPX(element, prop) {
1415
//This brutal hack is needed
1516
function getSizeBrutal(unit, element) {
1617
var testDIV = document.createElement('div')
17-
testDIV.style['font-size'] = '128' + unit
18+
testDIV.style['height'] = '128' + unit
1819
element.appendChild(testDIV)
19-
var size = getPropertyInPX(testDIV, 'font-size') / 128
20+
var size = getPropertyInPX(testDIV, 'height') / 128
2021
element.removeChild(testDIV)
2122
return size
2223
}
2324

2425
function toPX(str, element) {
26+
if (!str) return null
27+
2528
element = element || document.body
26-
str = (str || 'px').trim().toLowerCase()
29+
str = (str + '' || 'px').trim().toLowerCase()
2730
if(element === window || element === document) {
28-
element = document.body
31+
element = document.body
2932
}
33+
3034
switch(str) {
3135
case '%': //Ambiguous, not sure if we should use width or height
3236
return element.clientHeight / 100.0
@@ -55,6 +59,16 @@ function toPX(str, element) {
5559
return PIXELS_PER_INCH / 72
5660
case 'pc':
5761
return PIXELS_PER_INCH / 6
62+
case 'px':
63+
return 1
5864
}
59-
return 1
60-
}
65+
66+
// detect number of units
67+
var parts = parseUnit(str)
68+
if (!isNaN(parts[0]) && parts[1]) {
69+
var px = toPX(parts[1], element)
70+
return typeof px === 'number' ? parts[0] * px : null
71+
}
72+
73+
return null
74+
}

index.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
var parseUnit = require('parse-unit')
4+
5+
module.exports = toPX
6+
7+
var PIXELS_PER_INCH = 96
8+
9+
var defaults = {
10+
'ch': 8,
11+
'ex': 7.15625,
12+
'em': 16,
13+
'rem': 16,
14+
'in': PIXELS_PER_INCH,
15+
'cm': PIXELS_PER_INCH / 2.54,
16+
'mm': PIXELS_PER_INCH / 25.4,
17+
'pt': PIXELS_PER_INCH / 72,
18+
'pc': PIXELS_PER_INCH / 6,
19+
'px': 1
20+
}
21+
22+
function toPX(str) {
23+
if (!str) return null
24+
25+
if (defaults[str]) return defaults[str]
26+
27+
// detect number of units
28+
var parts = parseUnit(str)
29+
if (!isNaN(parts[0]) && parts[1]) {
30+
var px = toPX(parts[1])
31+
return typeof px === 'number' ? parts[0] * px : null
32+
}
33+
34+
return null
35+
}

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"name": "to-px",
33
"version": "1.0.1",
44
"description": "Convert any CSS unit to logical pixels (\"px\")",
5-
"main": "topx.js",
5+
"main": "index.js",
6+
"browser": "browser.js",
67
"directories": {
78
"test": "test"
89
},
@@ -14,7 +15,7 @@
1415
"tape": "^3.5.0"
1516
},
1617
"scripts": {
17-
"test": "tape test/*.js"
18+
"test": "tape test"
1819
},
1920
"repository": {
2021
"type": "git",

test/test.js renamed to test/index.js

+32-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
var tape = require('tape')
4-
var toPX = require('../topx')
4+
var toPX = require('../')
55
var parseUnit = require('parse-unit')
66
var almostEqual = require('almost-equal')
77

@@ -10,17 +10,32 @@ var units = ['em', 'ch', 'ex', 'rem', 'px', 'vw', 'vh', 'vmin', 'vmax', 'in', 'c
1010
var fontSizes = ['20px', '10px', '1em', '3in']
1111

1212
tape('test to-px', function(t) {
13+
if (typeof document === 'undefined') return t.end()
1314

1415
function testUnitsEmpirically(element) {
1516
var testDiv = document.createElement('div')
1617
element.appendChild(testDiv)
1718
for(var i=0; i<units.length; ++i) {
18-
testDiv.style['font-size'] = '128' + units[i]
19-
var expected = parseUnit(getComputedStyle(testDiv).getPropertyValue('font-size'))[0]/128
19+
testDiv.style['height'] = '128' + units[i]
20+
testDiv.style.position = 'absolute'
21+
testDiv.style.width = '1px'
22+
var expected = parseUnit(getComputedStyle(testDiv).getPropertyValue('height'))[0]/128
23+
var value = units[i]
2024
var actual = toPX(units[i], element)
2125

22-
t.ok(almostEqual(actual, expected, 0.005, almostEqual.FLT_EPSILON),
26+
t.ok(almostEqual(actual, expected, 0.005, almostEqual.FLT_EPSILON),
2327
'testing: ' + units[i] + ' ' + actual + ' ~ ' + expected)
28+
29+
value = '1' + units[i]
30+
actual = toPX(value, element)
31+
t.ok(almostEqual(actual, expected, 0.005, almostEqual.FLT_EPSILON),
32+
'testing: ' + value + ' ' + actual + ' ~ ' + expected)
33+
34+
value = Math.PI + units[i]
35+
actual = toPX(value, element)
36+
expected *= Math.PI
37+
t.ok(almostEqual(actual, expected, 0.005, almostEqual.FLT_EPSILON),
38+
'testing: ' + value + ' ' + actual + ' ~ ' + expected)
2439
}
2540
element.removeChild(testDiv)
2641
}
@@ -39,4 +54,16 @@ tape('test to-px', function(t) {
3954
testUnitsEmpirically(header)
4055

4156
t.end()
42-
})
57+
})
58+
59+
tape('edge cases', function (t) {
60+
t.equal(toPX(), null, 'no value')
61+
t.equal(toPX(''), null, 'empty string')
62+
t.equal(toPX(null), null, 'null value')
63+
t.equal(toPX('abc'), null, 'unknown units')
64+
t.equal(toPX('5def'), null, 'wrong units')
65+
t.equal(toPX('10'), null, 'number no units')
66+
t.equal(toPX(10), null, 'number value')
67+
68+
t.end()
69+
})

0 commit comments

Comments
 (0)