This commit is contained in:
Rasmus Andersson 2018-02-21 12:20:04 -08:00
parent bd425b8fb8
commit 2e929794e7
6 changed files with 299 additions and 41 deletions

View file

@ -60,6 +60,7 @@ endfor
<meta property="og:locale" content="en_US" />
</head>
<body>
<div id="hud-notification"><div class="msg">Hello</div></div>
<script src="{{url_root}}res/base.js?v={{ base_js_v }}"></script>
<div class="row menu">

View file

@ -39,16 +39,16 @@ endfor
<formula>
tracking =
<const>a</const> + <const>b</const> ×
<const>e</const><sup>(<const>c</const> × fontSize)</sup>
<const title="Base of natural logarithm; ≈2.718">e</const><sup>(<const>c</const> × <const>z</const>)</sup>
</formula>
<formula>
leading = <num>1.4</num> × fontSize
leading = round(<num data-binding="var-l">1.4</num> × <const>z</const>)
</formula>
<formula title="Values for Inter UI">
<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 class="wide-window"><const title="Base of natural logarithm">e</const><num>2.718</num></g>
<g><const>z</const> = font size</g>
</formula>
</p>
<p class="wide-window">
@ -251,10 +251,10 @@ var a = -0.016, b = 0.21, c = -0.18; // di=0.000532 on set-2018-02-20
var l = 1.4
// InterUIDynamicTracking takes the font size in points or pixels and returns
// the compensating tracking in EM.
// _InterUIDynamicTracking is a version of InterUIDynamicTracking that
// uses some global variables that are adjustable.
//
function InterUIDynamicTracking(fontSize, weightClass) {
function _InterUIDynamicTracking(fontSize, weightClass) {
// Note: weightClass is currently unused
//
// y = -0.01021241 + 0.3720623 * e ^ (-0.2808687 * x)
@ -263,7 +263,7 @@ function InterUIDynamicTracking(fontSize, weightClass) {
//
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
}
@ -322,7 +322,7 @@ Sample.prototype.idealDistance = function(fontSize) {
Sample.prototype.setFontSize = function(fontSize) {
this.fontSize = fontSize
this.tracking = baseTracking + InterUIDynamicTracking(fontSize, weightClass)
this.tracking = baseTracking + _InterUIDynamicTracking(fontSize, weightClass)
this.lineHeight = InterUIDynamicLineHeight(fontSize, weightClass)
this.maxBoxWidth = Math.round(fontSize * (this.tracking + 1) * 25)
@ -352,11 +352,11 @@ Sample.prototype.setFontSize = function(fontSize) {
}
Sample.prototype.cssProperties = function() {
return {
fontSize: round(this.fontSize, 3) + 'px',
letterSpacing: round(this.tracking, 3) + 'em',
lineHeight: round(this.lineHeight, 3) + 'px',
}
return [
['font-size', round(this.fontSize, 3) + 'px'],
['letter-spacing', round(this.tracking, 3) + 'em'],
['line-height', round(this.lineHeight, 3) + 'px'],
]
}
Sample.prototype.render = function() {
@ -479,7 +479,7 @@ function updateGraphPlot() {
graph.clear()
graph.plotLine(idealValuesList, '#0d3')
graph.plotf(function(x) {
return InterUIDynamicTracking(x, weightClass)
return _InterUIDynamicTracking(x, weightClass)
})
if (focusedSample) {
var graphedFontSize = Math.min(24, focusedSample.fontSize) // clamp to [-inf,24]
@ -496,13 +496,22 @@ codeOutput.addEventListener('focus', function(ev) {
codeOutput.select()
}, {passive:false,capture:true})
codeOutput.addEventListener('pointerdown', function(ev) {
// TODO: don't do this if codeOutput is focused
ev.preventDefault()
ev.stopPropagation()
codeOutput.select()
document.execCommand("copy")
HUDNotification.show('Copied to clipboard')
}, {passive:false,capture:true})
function updateCodeView() {
var s = ''
if (focusedSample) {
var cssprops = focusedSample.cssProperties()
var props = Object.keys(cssprops)
var props = focusedSample.cssProperties()
props.forEach(function(prop, i) {
s += prop + ': ' + cssprops[prop] + ';'
var name = prop[0], value = prop[1]
s += name + ': ' + value + ';'
if (i != props.length-1) {
s += '\n'
}

61
docs/index.css Normal file
View file

@ -0,0 +1,61 @@
#hidden-text-input {
position: absolute;
left:0;
top:0;
background: none;
border: none;
opacity: 0;
pointer-events: none;
}
.dynmet-calc {
font-size: 18px;
line-height: 26px;
user-select: text;
}
.dynmet-calc input {
border: none;
box-shadow: inset 0 -1px 0 0 rgba(255, 255, 255, 0.3);
background: transparent;
font: inherit;
color: inherit;
outline: none;
margin: 0 0.2em;
width: 40px;
text-align: center;
line-height: inherit;
color: #eee;
user-select: text;
}
.dynmet-calc input:focus {
color: #fff;
box-shadow: inset 0 -2px 0 0 rgb(43, 139, 247);
}
.dynmet-calc input[type=number]::-webkit-inner-spin-button,
.dynmet-calc input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.dynmet-calc .arrow {
margin: 0 0.8em;
color: #eee;
}
.dynmet-calc #dynmet-tracking {
box-shadow: none;
width: 57px;
margin-right: 0.1em;
color: #eee;
}
.dynmet-calc #dynmet-tracking.percent {
width: 34px;
}
.dynmet-calc #dynmet-unit:hover {
color: rgb(43, 139, 247);
}
.dynmet-calc #dynmet-unit:active {
color: white;
}

View file

@ -1,6 +1,23 @@
---
layout: default
---
{%
capture url_root
%}{% if site.safe == false %}/{% else %}/inter/{% endif
%}{%
endcapture %}{%
for file in site.static_files %}{%
assign _path = file.path | remove_first: "/inter" %}{%
if _path == "/index.css" %}{%
assign index_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
endif %}{%
endfor
%}
<link rel="stylesheet" href="index.css?v={{ index_css_v }}">
<input type="text" id="hidden-text-input">
<div class="row"><div>
<h1>The Inter UI font family</h1>
@ -46,8 +63,17 @@ layout: default
<p>&nbsp;</p>
<h2><a href="{{url_root}}dynmetrics/">Dynamic Metrics</a></h2>
<p class="dynmet-calc">
Font size
<input id="dynmet-font-size" type="number" value="12"
><span title='Display points — "px" in CSS, "pt" on iOS, "sp" on Android, and "pt" (1/72 of an inch) in print'>dp</span>
<span class="arrow">—></span>
letter spacing
<input id="dynmet-tracking" type="number" value="0.008">
<span id="dynmet-unit">em</span>
</p>
<p>
There's of course no absolute right or wrong when it comes to expressing yourself with typography, but Inter UI <em>Dynamic Metrics</em> provides guidelines for good typography. You simply provide the optical font size, and the tracking and leading is calculated for you to produce the best results.
There's of course no absolute right or wrong when it comes to expressing yourself with typography, but Inter UI <em>Dynamic Metrics</em> provides guidelines for good typography. You simply provide the optical font size, and the tracking and leading is calculated for you to produce the best results.<br>
<a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics —></a>
</p>
@ -297,11 +323,13 @@ layout: default
<a href="https://twitter.com/rsms" class="plain">@rsms</a>
</div></div>
<script>(function(){
<script>
// FAQ anchors
var av = document.querySelectorAll('ul.faq > li.q'), a, i, e, id, tn
for (i = 0; i < av.length; ++i) {
// FAQ anchors
(function(){
var av = document.querySelectorAll('ul.faq > li.q'), a, i, e, id, tn
for (i = 0; i < av.length; ++i) {
e = av[i]
tn = document.createTextNode('Q  ')
e.insertBefore(tn, e.firstChild)
@ -315,12 +343,104 @@ layout: default
e.innerText = ''
e.appendChild(a)
}
}
av = document.querySelectorAll('ul.faq > li.a')
for (i = 0; i < av.length; ++i) {
}
av = document.querySelectorAll('ul.faq > li.a')
for (i = 0; i < av.length; ++i) {
e = av[i]
tn = document.createTextNode('A  ')
e.insertBefore(tn, e.firstChild)
}
})();
// dynamic metrics calculator
(function(){
var hiddenTextInput = $('#hidden-text-input')
var fontSizeEl = $('#dynmet-font-size')
var trackingEl = $('#dynmet-tracking')
var unitEl = $('#dynmet-unit')
var unitFormatters = [
['em', 'em', function(fontSize, tracking) {
return tracking.toFixed(3)
}],
['px', 'px', function(fontSize, tracking) {
return (fontSize * tracking).toFixed(3)
}],
['%', 'percent', function(fontSize, tracking) {
return (tracking * 100).toFixed(1)
}],
]
var unitFormatter = unitFormatters[0][2]
function updateTracking() {
var fontSize = parseFloat(fontSizeEl.value)
if (isNaN(fontSize) || fontSize < 1) {
fontSizeEl.value = fontSize = 1
} else if (fontSize > 999) {
fontSizeEl.value = fontSize = 999
}
var tracking = InterUIDynamicTracking(fontSize)
trackingEl.value = unitFormatter(fontSize, tracking)
}
function toggleUnit() {
var unit = unitEl.innerText
var u, x = -1
for (var i = 0; i < unitFormatters.length; i++) {
if (x == -1) {
u = unitFormatters[i]
if (u[0] == unit) {
x = i + 1
if (x == unitFormatters.length) {
x = 0
}
u = unitFormatters[x]
}
}
trackingEl.classList.remove(unitFormatters[i][1]) // class name
}
unit = u[0]
trackingEl.classList.add(u[1])
unitFormatter = u[2]
unitEl.innerText = unit
updateTracking()
}
function onPointerdownUnit(ev) {
toggleUnit()
if (ev) {
ev.preventDefault()
ev.stopPropagation()
}
}
function onPointerdownTracking(ev) {
if (ev) {
ev.preventDefault()
ev.stopPropagation()
}
hiddenTextInput.value = trackingEl.value + unitEl.innerText
hiddenTextInput.select()
document.execCommand("copy")
trackingEl.select()
HUDNotification.show('Copied to clipboard')
}
var passiveListener = { passive: true, capture: false }
var activeListener = { capture: true }
fontSizeEl.addEventListener('input', updateTracking, passiveListener)
fontSizeEl.addEventListener('change', updateTracking, passiveListener)
unitEl.addEventListener('pointerdown', onPointerdownUnit, activeListener)
unitEl.addEventListener('mousedown', onPointerdownUnit, activeListener)
trackingEl.addEventListener('pointerdown', onPointerdownTracking, activeListener)
trackingEl.addEventListener('mousedown', onPointerdownTracking, activeListener)
updateTracking()
})();</script>

View file

@ -269,8 +269,8 @@ h1 > a, h2 > a, h3 > a {
color: #aaa;
}
.row.dark a:hover {
color: rgba(160, 190, 255, 1);
text-decoration: underline rgba(164, 188, 255, 0.6);
color: rgb(95, 170, 255);
text-decoration: underline rgb(95, 170, 255);
}
.row.dark h2, .row.dark h2 > a {
color: #ccc;
@ -467,6 +467,35 @@ box h3 {
margin-bottom:0.8em;
}
#hud-notification {
position: fixed;
bottom: 20px;
left: 0;
right: 0;
display: flex;
justify-content: center;
z-index: 9;
pointer-events: none;
}
#hud-notification .msg {
background: #000;
color: white;
height: 50px;
line-height: 50px;
font-size: 22px;
letter-spacing: -0.012em;
padding: 0 0.7em;
border-radius: 4px;
opacity: 0.1;
transition: 250ms all ease-in;
transform: translate3d(0, 71px, 0); /* height + bottom offset + 1 */
}
#hud-notification.visible .msg {
transform: translate3d(0, 0, 0);
transition: 120ms all cubic-bezier(0.25, 0.47, 0.44, 0.93);
opacity: 1;
}
/* ------------------------------------------------------ */

View file

@ -48,6 +48,44 @@ var timeNow = (
)
var HUDNotification = {
el: $('#hud-notification'),
timer: null,
visible: false,
show: function(message, duration) {
var n = this
n.el.firstChild.innerText = message
n.el.classList.add('visible')
if (n.visible) {
n.hide()
setTimeout(function(){ n.show(message, duration) }, 120)
return
}
n.visible = true
clearTimeout(n.timer)
n.timer = setTimeout(function(){ n.hide() }, duration || 1200)
},
hide: function() {
var n = this
if (n.visible) {
n.el.classList.remove('visible')
n.visible = false
}
}
}
// InterUIDynamicTracking takes the font size in points or pixels and returns
// the compensating tracking in EM.
//
function InterUIDynamicTracking(fontSize) {
// tracking = a + b * e ^ (c * fontSize)
return -0.016 + 0.21 * Math.pow(Math.E, -0.18 * fontSize)
}
// Mac or not? Maybe even a buggy Safari?
var isMac = false
if (!window.MSStream &&