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:
parent
118377c5ed
commit
fa662b9e1d
@ -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>
|
@ -75,6 +75,7 @@ formula.code {
|
||||
outline: none;
|
||||
margin-right: 50px;
|
||||
margin-bottom: 50px;
|
||||
min-width: 50px;
|
||||
}
|
||||
.samples .sample > * {
|
||||
display: block;
|
||||
|
@ -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>
|
||||
<g><const title="Constant b">b</const> = <num data-binding="var-b">0.21</num></g>
|
||||
<g><const title="Constant c">c</const> = <num data-binding="var-c">-0.18</num></g>
|
||||
<g><const title="Constant a">a</const> = <num data-binding="var-a">-0.02</num></g>
|
||||
<g><const title="Constant b">b</const> = <num data-binding="var-b">0.205</num></g>
|
||||
<g><const title="Constant c">c</const> = <num data-binding="var-c">-0.175</num></g>
|
||||
<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) }
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
XP–45 / vessel
|
||||
</livesample>
|
||||
|
||||
<hr>
|
||||
|
||||
<livesample contenteditable class="s1" data-ctxedit="sample1">
|
||||
Fabulous typography encountering spring
|
||||
|
98
misc/dynmet-search.js
Normal file
98
misc/dynmet-search.js
Normal 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()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user