From fa662b9e1d3fcc4272e07d2b34fd6b6168539185 Mon Sep 17 00:00:00 2001 From: Rasmus Andersson Date: Sat, 2 Feb 2019 21:01:00 -0800 Subject: [PATCH] website: dynamic metrics update --- docs/_includes/preload-font-files.html | 4 +- docs/dynmetrics/index.css | 1 + docs/dynmetrics/index.html | 52 +++++++------- docs/index.html | 8 +-- docs/res/base.js | 2 +- docs/samples/index.css | 21 ++++-- docs/samples/index.html | 11 +++ misc/dynmet-search.js | 98 ++++++++++++++++++++++++++ 8 files changed, 161 insertions(+), 36 deletions(-) create mode 100644 misc/dynmet-search.js diff --git a/docs/_includes/preload-font-files.html b/docs/_includes/preload-font-files.html index 9533ce0b5..34847f426 100644 --- a/docs/_includes/preload-font-files.html +++ b/docs/_includes/preload-font-files.html @@ -1,2 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/dynmetrics/index.css b/docs/dynmetrics/index.css index f4328c6b2..cd9fb98cf 100644 --- a/docs/dynmetrics/index.css +++ b/docs/dynmetrics/index.css @@ -75,6 +75,7 @@ formula.code { outline: none; margin-right: 50px; margin-bottom: 50px; + min-width: 50px; } .samples .sample > * { display: block; diff --git a/docs/dynmetrics/index.html b/docs/dynmetrics/index.html index 9b5022c3f..e43be7c9c 100644 --- a/docs/dynmetrics/index.html +++ b/docs/dynmetrics/index.html @@ -32,7 +32,7 @@ endfor yourself with typography, but Inter Dynamic Metrics provides guidelines for how to best use Inter. You simply provide the optical font size, - and the tracking and leading is calculated for you through the following + and the tracking and line height is calculated for you through the following formula:

@@ -42,12 +42,12 @@ endfor e(c × z) - leading = round(1.4 × z) + line height = 1.4 × z - a = -0.016    - b = 0.21    - c = -0.18    + a = -0.02    + b = 0.205    + c = -0.175    z = font size

@@ -194,24 +194,24 @@ function parseValues(s) { } setIdealValues({ - // 2018-09-28 - 6: 0.054, - 7: 0.042, - 8: 0.033, - 9: 0.025, - 10: 0.018, - 11: 0.012, - 12: 0.008, - 13: 0.004, - 14: 0, - 15: -0.002, + 6: 0.021, + 7: 0.017, + 8: 0.013, + 9: 0.01, + 10: 0.007, + 11: 0.005, + 12: 0.002, + 13: 0, + 14: -0.002, + 15: -0.004, 16: -0.005, 17: -0.007, 18: -0.008, - 20: -0.011, - 24: -0.014, + 20: -0.01, + 24: -0.013, 30: -0.016, - 40: -0.017, + 40: -0.02, + 80: -0.02, }) @@ -222,7 +222,9 @@ setIdealValues({ // var a = -0.015, b = 0.283, c = -0.23; // di=0.00221 on set-2018-02-18 // var a = -0.0149, b = 0.298, c = -0.23; // di=0.000484 on set-2018-02-19 // var a = -0.018, b = 0.21, c = -0.18; // di=0.000532 on set-2018-02-20 -var a = -0.017, b = 0.202, c = -0.175; // di=0.000247 on 2018-09-28 +// var a = -0.017, b = 0.202, c = -0.175; // 2018-09-28 +var a = -0.02, b = 0.0755, c = -0.102 // 2019-02-02 + var l = 1.4 @@ -238,10 +240,6 @@ function _InterDynamicTracking(fontSize, weightClass) { // See https://gist.github.com/rsms/8efdbca5f8145a584ed08a7c3d6e5788 // return a + b * Math.pow(Math.E, c * fontSize) - // [6 - 38] 0.05798 .. -0.01099 (midpoint = 12.533) - // - // y = 0.025 - (ln(x) * 0.01) - // return 0.025 - Math.log(fontSize) * 0.01 } @@ -335,6 +333,11 @@ Sample.prototype.cssProperties = function() { ] } +Sample.prototype.setText = function(text) { + this.contentEl.innerText = text + this.render() +} + Sample.prototype.render = function() { this.style.fontSize = this.fontSize + 'px' this.style.letterSpacing = this.tracking + 'em' @@ -393,6 +396,7 @@ function initSamples() { samples.push(new Sample(24)) samples.push(new Sample(30)) samples.push(new Sample(40)) + samples.push(new Sample(80)) // connect focus events var onSampleReceivedFocus = function() { setSelectedSample(this) } diff --git a/docs/index.html b/docs/index.html index 5ec838edc..edbd10835 100644 --- a/docs/index.html +++ b/docs/index.html @@ -100,8 +100,8 @@ html { font-family: 'Inter', sans-serif; }

Weights & Styles

- There are six weights, each with italic counterparts, - making a total of 12 styles. + There are nine weights, each with italic counterparts, + making a total of 18 styles.

@@ -564,10 +564,10 @@ var unitEl = $('#dynmet-unit') var unitFormatters = [ ['em', 'em', function(fontSize, tracking) { - return tracking.toFixed(3) + return tracking.toFixed(3).replace(/(?:\.000|0+)$/, '') }], ['px', 'px', function(fontSize, tracking) { - return (fontSize * tracking).toFixed(1) + return (fontSize * tracking).toFixed(2).replace(/(?:\.00|0+)$/, '') }], ['%', 'percent', function(fontSize, tracking) { return (tracking * 100).toFixed(1) diff --git a/docs/res/base.js b/docs/res/base.js index ba858b62e..40188360e 100644 --- a/docs/res/base.js +++ b/docs/res/base.js @@ -81,8 +81,8 @@ var HUDNotification = { // the compensating tracking in EM. // function InterDynamicTracking(fontSize) { + var a = -0.02, b = 0.0755, c = -0.102; // tracking = a + b * e ^ (c * fontSize) - var a = -0.017, b = 0.202, c = -0.175; return a + b * Math.pow(Math.E, c * fontSize) } diff --git a/docs/samples/index.css b/docs/samples/index.css index 6114ae255..a1234d8cc 100644 --- a/docs/samples/index.css +++ b/docs/samples/index.css @@ -8,22 +8,33 @@ body { text-align:center; } +.live > hr { + margin: 3rem 0 4rem 0; + background: black; + height: 2px; + border: none; +} + livesample { display: block; color: #111; outline: none; - /*padding-left: 20px; + margin-top: 1rem; + margin-bottom: 1rem; +} + +/*livesample { + padding-left: 20px; border-left: 2px solid transparent; - margin-left:-22px;*/ - margin-top: 1em; - margin-bottom: 1.6em; + margin-left:-22px; } livesample:hover { border-left-color: rgb(3, 102, 214); } -/*livesample:focus { +livesample:focus { border-left-color: #eee; }*/ + livesample > p { margin-top: 0; } diff --git a/docs/samples/index.html b/docs/samples/index.html index 88f389c88..3784fcccb 100644 --- a/docs/samples/index.html +++ b/docs/samples/index.html @@ -28,6 +28,17 @@ endfor
+ + Interfacing mechanisms + + + + XP–45 / vessel + + +
Fabulous typography encountering spring diff --git a/misc/dynmet-search.js b/misc/dynmet-search.js new file mode 100644 index 000000000..33189b8ea --- /dev/null +++ b/misc/dynmet-search.js @@ -0,0 +1,98 @@ +// +// Program that searches for optimal a,b,c values for dynamic metrics. +// +// Provide ideal tracking values for font sizes in idealTracking and start +// this program. It will run forever and print to stdout when it finds +// better a,b,c values that brings you closer to the ideal values. +// +// These are the initial a,b,c values. (Update if you find better values.) +let a = -0.02, b = 0.0755, c = -0.1021 // 0.00092 +// +// These are the ideal tracking values. +let idealTracking = { + // 6: 0.05, + // 7: 0.04, + // 8: 0.03, + 9: 0.01, + // 10: 0.015, + 11: 0.005, + 12: 0.0025, + 13: 0, + // 14: 0, + // 15: -0.002, + 16: -0.005, + // 17: -0.008, + 18: -0.01, + // 20: -0.014, + // 24: -0.016, + // 30: -0.019, + 40: -0.022, +} + + +let idealTrackingList = Object.keys(idealTracking).map(fontSize => + [fontSize, idealTracking[fontSize]] +) + +function sample(a, b, c) { + let idealDist = 0.0 + for (let [fontSize, idealTracking] of idealTrackingList) { + + let tracking = a + b * Math.pow(Math.E, c * fontSize) + + let dist = Math.abs(tracking - idealTracking) + + idealDist += dist + // console.log(`${fontSize} d=${tracking - idealTracking} d'=${dist}`) + } + // console.log(`idealDist=${idealDist}`) + return idealDist / idealTrackingList.length +} + +const prec = 4 // precision +let bestConstants = { a, b, c } +let isneg = { + a: a < 0, + b: b < 0, + c: c < 0, +} +let bestDistance = sample(a, b, c) + +console.log( + '------------------------------------------------------------------\n' + + `| Started at ${(new Date()).toLocaleString()} with initial values:\n` + + `| a = ${bestConstants.a}, b = ${bestConstants.b},` + + ` c = ${bestConstants.c} // D ${bestDistance.toFixed(5)}\n` + + `| Ctrl-C to end.\n` + + '------------------------------------------------------------------' +) + +function logNewBest() { + console.log( + `new best: a = ${a.toFixed(prec)}, b = ${b.toFixed(prec)}, c = ${c.toFixed(prec)} // D ${bestDistance.toFixed(5)}` + ) +} + +while (true) { + // a = parseFloat((bestConstants.a * ((Math.random() * 2.0) - 1.0)).toFixed(prec)) + // b = parseFloat((bestConstants.b * ((Math.random() * 2.0) - 1.0)).toFixed(prec)) + // c = parseFloat((bestConstants.c * ((Math.random() * 2.0) - 1.0)).toFixed(prec)) + + let a2 = bestConstants.a * ((Math.random() * 2.0) - 1.0) + let b2 = bestConstants.b * ((Math.random() * 2.0) - 1.0) + let c2 = bestConstants.c * ((Math.random() * 2.0) - 1.0) + + if (isneg.a) { if (a2 > 0) { a2 = a } } else if (a2 < 0) { a2 = a } + if (isneg.b) { if (b2 > 0) { b2 = b } } else if (b2 < 0) { b2 = b } + if (isneg.c) { if (c2 > 0) { c2 = c } } else if (c2 < 0) { c2 = c } + + a = a2 + b = b2 + c = c2 + + let dist = sample(a, b, c) + if (dist < bestDistance) { + bestDistance = dist + logNewBest() + } +}