Permalink
Browse files

Initial commit.

1 parent 8da7625 commit c756d047c3b1cfd792e4f0d644e701b008c6037b @borismus committed May 2, 2012
Showing with 245 additions and 3 deletions.
  1. +7 −3 README.md
  2. +29 −0 controls.html
  3. +3 −0 img/cloud.svg
  4. +3 −0 img/plus.svg
  5. +3 −0 img/search.svg
  6. +3 −0 img/shuffle.svg
  7. +3 −0 img/simple.svg
  8. +47 −0 physical.js
  9. +55 −0 sample.html
  10. +92 −0 unit-converter.js
View
@@ -1,4 +1,8 @@
-physical-units
-==============
+# Physical Units on the web
-A modest proposal for using real physical units for web-based UIs.
+Problem: CSS units that sound like they should be physical (mm, cm, in,
+etc) actually aren't.
+
+This is an experiment that makes these units truly physical.
+
+This experimental library works only on some devices, but automatically
View
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1">
+</head>
+<body>
+ <div>
+ <h2>Touch target.</h2>
+ <button style="width: 40mm; height: 9mm; -webkit-appearance: none;">40x9mm touch target</button>
+ </div>
+
+ <div>
+ <h2>2x2in image.</h2>
+
+ <img src="img/search.svg" style="width: 2in; height: 2in;" />
+ </div>
+
+ <div>
+ <h2>font-size: 3mm; line-height: 4mm; text.</h2>
+
+ <p style="font-size: 3mm; line-height: 4mm">
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
+ </p>
+ </div>
+
+ <script src="unit-converter.js"></script>
+ <script src="physical.js"></script>
+</body>
+</html>
View
@@ -0,0 +1,3 @@
+<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.562,24.812c-3.313,0-6-2.687-6-6l0,0c0.002-2.659,1.734-4.899,4.127-5.684l0,0c0.083-2.26,1.937-4.064,4.216-4.066l0,0c0.73,0,1.415,0.19,2.01,0.517l0,0c1.266-2.105,3.57-3.516,6.208-3.517l0,0c3.947,0.002,7.157,3.155,7.248,7.079l0,0c2.362,0.804,4.062,3.034,4.064,5.671l0,0c0,3.313-2.687,6-6,6l0,0H7.562L7.562,24.812zM24.163,14.887c-0.511-0.095-0.864-0.562-0.815-1.079l0,0c0.017-0.171,0.027-0.336,0.027-0.497l0,0c-0.007-2.899-2.352-5.245-5.251-5.249l0,0c-2.249-0.002-4.162,1.418-4.911,3.41l0,0c-0.122,0.323-0.406,0.564-0.748,0.63l0,0c-0.34,0.066-0.694-0.052-0.927-0.309l0,0c-0.416-0.453-0.986-0.731-1.633-0.731l0,0c-1.225,0.002-2.216,0.993-2.22,2.218l0,0c0,0.136,0.017,0.276,0.045,0.424l0,0c0.049,0.266-0.008,0.54-0.163,0.762l0,0c-0.155,0.223-0.392,0.371-0.657,0.414l0,0c-1.9,0.313-3.352,1.949-3.35,3.931l0,0c0.004,2.209,1.792,3.995,4.001,4.001l0,0h15.874c2.209-0.006,3.994-1.792,3.999-4.001l0,0C27.438,16.854,26.024,15.231,24.163,14.887L24.163,14.887" />
+</svg>
View
@@ -0,0 +1,3 @@
+<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
+<path d="M25.979,12.896 19.312,12.896 19.312,6.229 12.647,6.229 12.647,12.896 5.979,12.896 5.979,19.562 12.647,19.562 12.647,26.229 19.312,26.229 19.312,19.562 25.979,19.562z" />
+</svg>
View
@@ -0,0 +1,3 @@
+<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
+<path d="M29.772,26.433l-7.126-7.126c0.96-1.583,1.523-3.435,1.524-5.421C24.169,8.093,19.478,3.401,13.688,3.399C7.897,3.401,3.204,8.093,3.204,13.885c0,5.789,4.693,10.481,10.484,10.481c1.987,0,3.839-0.563,5.422-1.523l7.128,7.127L29.772,26.433zM7.203,13.885c0.006-3.582,2.903-6.478,6.484-6.486c3.579,0.008,6.478,2.904,6.484,6.486c-0.007,3.58-2.905,6.476-6.484,6.484C10.106,20.361,7.209,17.465,7.203,13.885z" />
+</svg>
View
@@ -0,0 +1,3 @@
+<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
+<path d="M21.786,20.654c-0.618-0.195-1.407-0.703-2.291-1.587c-0.757-0.742-1.539-1.698-2.34-2.741c-0.191,0.256-0.382,0.51-0.574,0.77c-0.524,0.709-1.059,1.424-1.604,2.127c1.904,2.31,3.88,4.578,6.809,4.952v2.701l7.556-4.362l-7.556-4.362V20.654zM9.192,11.933c0.756,0.741,1.538,1.697,2.339,2.739c0.195-0.262,0.39-0.521,0.587-0.788c0.52-0.703,1.051-1.412,1.592-2.11c-2.032-2.463-4.133-4.907-7.396-5.025h-3.5v3.5h3.5C6.969,10.223,7.996,10.735,9.192,11.933zM21.786,10.341v2.535l7.556-4.363l-7.556-4.363v2.647c-1.904,0.219-3.425,1.348-4.751,2.644c-2.196,2.183-4.116,5.167-6.011,7.538c-1.867,2.438-3.741,3.888-4.712,3.771h-3.5v3.5h3.5c2.185-0.029,3.879-1.266,5.34-2.693c2.194-2.184,4.116-5.167,6.009-7.538C19.205,12.003,20.746,10.679,21.786,10.341z"/>
+</svg>
View
@@ -0,0 +1,3 @@
+<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
+<path d="M25.979,12.896 19.312,12.896 19.312,6.229 12.647,6.229 12.647,12.896 5.979,12.896 5.979,19.562 12.647,19.562 12.647,26.229 19.312,26.229 19.312,19.562 25.979,19.562z" />
+</svg>
View
@@ -0,0 +1,47 @@
+var STYLES = [
+ 'width', 'height',
+ 'min-width', 'min-height',
+ 'max-width', 'max-height',
+ 'margin-left', 'margin-right', 'margin-top', 'margin-bottom',
+ 'font-size', 'line-height',
+ 'top', 'bottom', 'left', 'right'];
+
+var converter = new UnitConverter();
+
+/**
+ * Gets all elements in the page.
+ */
+function getAllElements() {
+ var treeWalker = document.createTreeWalker(document.body,
+ NodeFilter.SHOW_ELEMENT, {
+ acceptNode: function(node) {
+ return NodeFilter.FILTER_ACCEPT;
+ }
+ }, false
+ );
+ var nodeList = [];
+ while(treeWalker.nextNode()) nodeList.push(treeWalker.currentNode);
+ return nodeList;
+}
+
+/**
+ * Given an element and a CSS style name, check if real units are specified,
+ * and if so, change to pixels.
+ */
+function convertUnits(element) {
+ // Iterate through important styles, and convert to px if they are specified.
+ for (var i = 0; i < STYLES.length; i++) {
+ var styleName = STYLES[i];
+ var style = element.style[styleName]
+ if (style) {
+ var newStyle = converter.toPixels(style);
+ element.style[styleName] = newStyle;
+ }
+ }
+}
+
+var elements = getAllElements();
+for (var i = 0; i < elements.length; i++) {
+ var el = elements[i];
+ convertUnits(el);
+}
View
@@ -0,0 +1,55 @@
+<!doctype html>
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1">
+ <style>
+ * { margin: 0; padding: 0 }
+ button { border: 1px solid #ddd; -webkit-appearance: none; background: transparent; }
+ header, article, footer { position: fixed; width: 100%; overflow: hidden; }
+ header, footer { background: #eee; }
+ article { overflow: auto; -webkit-overflow-scrolling: touch; }
+ footer div {
+ float: left;
+ width: 21%;
+ padding: 0 2%;
+ }
+ footer img {
+ width: auto;
+ height: 100%;
+ }
+ </style>
+</head>
+<body>
+ <header style="height: 8mm;">
+ <button style="float: left; min-width: 15mm; height: 8mm;">Mailboxes</button>
+ <button style="float: right; min-width: 15mm; height: 8mm;">Edit</button>
+ <h1 style="float: left; margin-left: 3mm; font-size: 7mm;">Title</h1>
+ </header>
+
+ <article style="top: 8mm; bottom: 8mm;">
+ <p style="line-height: 4mm; font-size: 3mm;">
+ (line-height: 5mm, font-size: 4mm) There's a holdout in the Bronx, Brooklyn's broken out in fights. There's a traffic jam in Harlem that's backed up to Jackson Heights. There's a Scout troop short a child, Khrushchev's due at Idelwyld... Car 54, where are you?
+
+ We never thought of findin' a place where we belong. Don't have to stand alone, we'll never let you fall. Don't need permission to decide what you believe. You gotta learn something when we meet you after school. I said jump, down on Jump Street. I said jump, down on Jump Street. Your friends will be there when your back is to the wall. You'll find you'll need us cause there's no one else to call. When it was hopeless a decision is what you need. You'd better be ready cause' your runnin' outta time. Say jump, 21 Jump, Street.
+ </p>
+ </article>
+
+ <footer style="bottom: 0; height: 8mm;">
+ <div>
+ <img style="max-height: 8mm;" src="img/search.svg"/>
+ </div>
+ <div>
+ <img style="max-height: 8mm;" src="img/plus.svg"/>
+ </div>
+ <div>
+ <img style="max-height: 8mm;" src="img/shuffle.svg"/>
+ </div>
+ <div>
+ <img style="max-height: 8mm;" src="img/cloud.svg"/>
+ </div>
+ </footer>
+
+ <script src="unit-converter.js"></script>
+ <script src="physical.js"></script>
+</body>
+</html>
View
@@ -0,0 +1,92 @@
+(function(exports) {
+// Array of mappings between user agent regular expressions and DPIs.
+var DPIs = {
+ "iPhone": 163,
+ "iPad": 132,
+ "Galaxy Nexus": 158,
+ "Transformer Prime": 149,
+ ".*": 128 // Fallback to MacBook Air 13" and MacBook Pro 15".
+};
+
+// Chrome ignores units that it doesn't understand, so forced to override
+// behavior of existing units. Browser vendors should create new units so that
+// sites aren't broken.
+//
+//var PHYSICAL_UNITS = {'realin': 1, 'realmm': 25.4, 'realcm': 2.54};
+var PHYSICAL_UNITS = {'in': 1, 'mm': 25.4, 'cm': 2.54};
+var UNIT_REGEX = /([.0-9]+)([a-z]+)/;
+
+function UnitConverter() {
+ var scalingFactor = null;
+
+ for (var reString in DPIs) {
+ // Check if the user agent matches against one of the DPIs
+ var re = new RegExp(reString);
+ if (navigator.userAgent.match(re)) {
+ // If it does, calculate the scaling factor
+ scalingFactor = DPIs[reString];
+ break;
+ }
+ }
+
+ this.scalingFactor = scalingFactor;
+}
+
+/**
+ * @return The number of pixels, given inches.
+ */
+UnitConverter.prototype.inchesToPixels = function(inches) {
+ return inches * scalingFactor;
+};
+
+/**
+ * @return The number of inches, given pixels.
+ */
+UnitConverter.prototype.pixelsToInches = function(pixels) {
+ return pixels / scalingFactor;
+};
+
+/**
+ * Given a string in the format Nunit, return the corresponding string in
+ * pixels.
+ *
+ * Example input: "5realin", output: "23px".
+ *
+ * If an unknown unit is specified, return the original string.
+ */
+UnitConverter.prototype.toPixels = function(dimensionString) {
+ var match = dimensionString.match(UNIT_REGEX);
+ var value = match[1];
+ var unit = match[2];
+
+ // Check if the unit is supported.
+ if (!PHYSICAL_UNITS[unit]) {
+ return dimensionString;
+ }
+ // If it is, convert to inches.
+ var unitsPerInch = PHYSICAL_UNITS[unit];
+ var inches = value / unitsPerInch;
+ // Convert inches to pixels.
+ var pixels = parseInt(inches * this.scalingFactor);
+ return pixels + 'px';
+};
+
+/**
+ * @return The number of pixels, given inches.
+ */
+UnitConverter.prototype.mmToPixels = function(mms) {
+ var inches = mms / PHYSICAL_UNITS['mm'];
+ return this.inchesToPixels(inches);
+}
+
+UnitConverter.prototype.physicalWidth = function() {
+ return pixelsToInches(window.offsetWidth);
+}
+
+UnitConverter.prototype.physicalHeight = function() {
+ return pixelsToInches(window.offsetHeight);
+}
+
+exports.UnitConverter = UnitConverter;
+
+})(window);

0 comments on commit c756d04

Please sign in to comment.