1
1
mirror of https://github.com/rsms/inter.git synced 2024-12-23 23:51:39 +03:00

website: dynamic metrics update

This commit is contained in:
Rasmus Andersson 2019-02-02 21:01:00 -08:00
parent 118377c5ed
commit fa662b9e1d
8 changed files with 161 additions and 36 deletions

View File

@ -1,2 +1,2 @@
<link rel="preload" href="font-files/Inter-upright.var.woff2?v=3.3" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="font-files/Inter-italic.var.woff2?v=3.3" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/font-files/Inter-upright.var.woff2?v=3.3" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/font-files/Inter-italic.var.woff2?v=3.3" as="font" type="font/woff2" crossorigin>

View File

@ -75,6 +75,7 @@ formula.code {
outline: none;
margin-right: 50px;
margin-bottom: 50px;
min-width: 50px;
}
.samples .sample > * {
display: block;

View File

@ -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:
</p>
<p>
@ -42,12 +42,12 @@ endfor
<const title="Base of natural logarithm; ≈2.718">e</const><sup>(<const>c</const> × <const>z</const>)</sup>
</formula>
<formula>
leading = round(<num data-binding="var-l">1.4</num> × <const>z</const>)
line height = <num data-binding="var-l">1.4</num> × <const>z</const>
</formula>
<formula title="Values for Inter">
<g><const title="Constant a">a</const> = <num data-binding="var-a">-0.016</num></g> &nbsp;&nbsp;
<g><const title="Constant b">b</const> = <num data-binding="var-b">0.21</num></g> &nbsp;&nbsp;
<g><const title="Constant c">c</const> = <num data-binding="var-c">-0.18</num></g> &nbsp;&nbsp;
<g><const title="Constant a">a</const> = <num data-binding="var-a">-0.02</num></g> &nbsp;&nbsp;
<g><const title="Constant b">b</const> = <num data-binding="var-b">0.205</num></g> &nbsp;&nbsp;
<g><const title="Constant c">c</const> = <num data-binding="var-c">-0.175</num></g> &nbsp;&nbsp;
<g><const>z</const> = font size</g>
</formula>
</p>
@ -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) }

View File

@ -100,8 +100,8 @@ html { font-family: 'Inter', sans-serif; }
<div class="row"><div>
<h2><a id="weights" href="#weights">Weights & Styles</a></h2>
<p>
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.
</p>
<img src="res/weights-and-styles.svg" style="opacity:0.88;width:100%;display:block;margin:3em 0 3em 0">
</div></div>
@ -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)

View File

@ -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)
}

View File

@ -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;
}

View File

@ -28,6 +28,17 @@ endfor
<div class="row"><div>
<div class="live">
<livesample data-ctxedit="sample-x1"
style="font-size:80px;line-height:1.0" contenteditable>
Interfacing mechanisms
</livesample>
<livesample data-ctxedit="sample-x2"
style="font-weight:100;font-size:80px;line-height:1.2" contenteditable>
XP45 / vessel
</livesample>
<hr>
<livesample contenteditable class="s1" data-ctxedit="sample1">
Fabulous typography encountering spring

98
misc/dynmet-search.js Normal file
View File

@ -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()
}
}