website: major update
This commit is contained in:
parent
761638ef42
commit
9f367901ef
22 changed files with 2139 additions and 1030 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -17,6 +17,7 @@ nohup.out
|
|||
build
|
||||
/_*
|
||||
/docs/lab/fonts
|
||||
/docs/_site
|
||||
|
||||
src/FontInspector.html
|
||||
src/svg
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -159,13 +159,13 @@ install_otf: all_otf
|
|||
install: install_otf
|
||||
|
||||
|
||||
geninfo: docs/info.json docs/lab/glyphinfo.json docs/glyphs/metrics.json
|
||||
geninfo: docs/_data/fontinfo.json docs/lab/glyphinfo.json docs/glyphs/metrics.json
|
||||
|
||||
src/glyphorder.txt: src/Inter-UI-Regular.ufo/lib.plist src/Inter-UI-Black.ufo/lib.plist src/diacritics.txt misc/gen-glyphorder.py
|
||||
misc/gen-glyphorder.py src/Inter-UI-*.ufo > src/glyphorder.txt
|
||||
|
||||
docs/info.json: misc/fontinfo.py docs/font-files/Inter-UI-*.otf
|
||||
misc/fontinfo.py -pretty docs/font-files/Inter-UI-Regular.otf > docs/info.json
|
||||
docs/_data/fontinfo.json: misc/fontinfo.py docs/font-files/Inter-UI-*.otf
|
||||
misc/fontinfo.py -pretty docs/font-files/Inter-UI-Regular.otf > docs/_data/fontinfo.json
|
||||
|
||||
docs/lab/glyphinfo.json: _local/UnicodeData.txt src/glyphorder.txt src/fontbuild.cfg misc/gen-glyphinfo.py
|
||||
misc/gen-glyphinfo.py -ucd _local/UnicodeData.txt \
|
||||
|
|
|
|||
10
docs/_config.yml
Normal file
10
docs/_config.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
port: 3000
|
||||
lsi: false
|
||||
permalink: /:title
|
||||
markdown: kramdown
|
||||
# Since GH pages override this to "true", we test this value to see if we are running locally
|
||||
safe: false
|
||||
kramdown:
|
||||
input: GFM
|
||||
auto_ids: true
|
||||
hard_wrap: false
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"Inter UI Regular:2018:86daccf": {
|
||||
[
|
||||
{
|
||||
"head": {
|
||||
"checkSumAdjustment": 3690365233,
|
||||
"created": 3563720514,
|
||||
|
|
@ -117,6 +117,7 @@
|
|||
"minMemType42": 0,
|
||||
"underlinePosition": -422,
|
||||
"underlineThickness": 170
|
||||
}
|
||||
},
|
||||
"version": "2.5"
|
||||
}
|
||||
}
|
||||
]
|
||||
46
docs/_includes/autoreload-in-debug.html
Normal file
46
docs/_includes/autoreload-in-debug.html
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{% if site.safe == false %}
|
||||
<!-- During authoring, this automatically reloads the post as its changing -->
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var qs = document.location.search;
|
||||
var current_etag = qs.match(/etag=("?[a-zA-Z0-9_-]+)/);
|
||||
if (current_etag !== null) { current_etag = current_etag[1]; }
|
||||
var scrolly = qs.match(/scrolly=([0-9]+)/);
|
||||
if (scrolly) {
|
||||
scrolly = parseInt(scrolly[1]);
|
||||
if (scrolly > 0) {
|
||||
window.scrollTo(window.scrollX, scrolly);
|
||||
setTimeout(function () {
|
||||
window.scrollTo(window.scrollX, scrolly);
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function check() {
|
||||
var r = new XMLHttpRequest();
|
||||
var url = document.location.href + ((qs && qs !== '') ? '&' : '?') + 'r=' + Math.random();
|
||||
r.open('GET', url, true);
|
||||
r.onreadystatechange = function() {
|
||||
if (r.readyState == 4){
|
||||
var found_etag = r.getResponseHeader('Etag');
|
||||
if (found_etag) {
|
||||
found_etag = found_etag.replace(/^"|"$/g);
|
||||
}
|
||||
//console.log('current_etag:', current_etag, 'found_etag:', found_etag);
|
||||
if (current_etag === null) {
|
||||
current_etag = found_etag;
|
||||
} else if (found_etag !== current_etag) {
|
||||
document.location.search =
|
||||
'?etag=' + encodeURIComponent(found_etag) +
|
||||
'&scrolly=' + window.scrollY;
|
||||
return;
|
||||
}
|
||||
setTimeout(check, 500);
|
||||
}
|
||||
};
|
||||
r.send(null);
|
||||
}
|
||||
check();
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
||||
88
docs/_layouts/default.html
Normal file
88
docs/_layouts/default.html
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
{%
|
||||
assign build_version = site.time | date: "%Y%m%d%H%M%S" %}{%
|
||||
assign description = "Inter UI is a new typeface optimized for computer user interfaces" %}{%
|
||||
|
||||
capture url_root
|
||||
%}{% if site.safe == false %}/{% else %}/inter/{% endif
|
||||
%}{%
|
||||
endcapture %}{%
|
||||
|
||||
capture release_version
|
||||
%}{{ site.data.fontinfo[0].version }}{%
|
||||
endcapture %}{%
|
||||
|
||||
capture download_url
|
||||
%}https://github.com/rsms/inter/releases/download/v{{ release_version }}/Inter-UI-{{ release_version }}.zip{%
|
||||
endcapture %}{%
|
||||
|
||||
for file in site.static_files %}{%
|
||||
assign _path = file.path | remove_first: "/inter" %}{%
|
||||
if _path == "/res/base.css" %}{%
|
||||
assign base_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/base.js" %}{%
|
||||
assign base_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
endif %}{%
|
||||
endfor
|
||||
|
||||
%}<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% if page.title %}{{ page.title }} — Inter UI{% else %}Inter UI font family{% endif %}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" href="{{url_root}}inter-ui.css?v={{ release_version }}">
|
||||
<link rel="stylesheet" href="{{url_root}}res/base.css?v={{ base_css_v }}">
|
||||
<link rel="icon" type="image/png" href="{{url_root}}res/favicon.png">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta property="twitter:card" content="summary">
|
||||
<meta property="twitter:site" content="@rsms">
|
||||
<meta property="twitter:creator" content="@rsms">
|
||||
<meta property="description" content="{{description}}">
|
||||
<meta property="og:description" content="{{description}}">
|
||||
<meta property="twitter:description" content="{{description}}">
|
||||
{% if page.title %}
|
||||
<meta property="og:title" content="{{ page.title }}">
|
||||
<meta property="twitter:title" content="{{ page.title }}">
|
||||
{% endif %}
|
||||
{% if page.og_image_url %}
|
||||
<meta property="og:image" content="{{ page.og_image_url }}">
|
||||
<meta property="twitter:image" content="{{ page.og_image_url }}">
|
||||
{% else %}
|
||||
<meta property="og:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="twitter:image" content="https://rsms.me/inter/res/poster.png">
|
||||
{% endif %}
|
||||
<meta property="og:url" content="https://rsms.me/inter/{{ page.url | remove_first:'index.html' }}">
|
||||
<meta property="fb:app_id" content="38027689216">
|
||||
<meta property="og:site_name" content="rsms.me/inter">
|
||||
<meta property="og:type" content="product">
|
||||
<meta property="og:locale" content="en_US" />
|
||||
</head>
|
||||
<body>
|
||||
<script src="{{url_root}}res/base.js?v={{ base_js_v }}"></script>
|
||||
|
||||
<div class="row menu">
|
||||
<ul class="menu">
|
||||
<li class="home"><a href="{{url_root}}">Inter UI</a></li>
|
||||
<li><a class="download-link" href="{{ download_url }}"
|
||||
>Download</a></li>
|
||||
<li><a href="{{url_root}}samples/"
|
||||
{% if page.url contains "/samples/" %}class="active"{% endif %}
|
||||
>Samples</a></li>
|
||||
<li><a href="{{url_root}}lab/"
|
||||
{% if page.url contains "/lab/" %}class="active"{% endif %}
|
||||
>Playground</a></li>
|
||||
<li><a href="https://github.com/rsms/inter/"
|
||||
>Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
{% if site.safe == true %}
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-105091131-2"></script>
|
||||
{% endif %}
|
||||
{% include autoreload-in-debug.html %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
pushd res >/dev/null
|
||||
|
||||
9
docs/_scripts/serve.sh
Executable file
9
docs/_scripts/serve.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [ ! -s lab/fonts ]; then
|
||||
ln -s ../../build/dist lab/fonts
|
||||
fi
|
||||
|
||||
jekyll serve --limit_posts 20 --watch --host 127.0.0.1 --port 3002 --open-url
|
||||
262
docs/dynmetrics/index.css
Normal file
262
docs/dynmetrics/index.css
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
body {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
const {
|
||||
display: inline;
|
||||
font-size: 1.2em;
|
||||
font-style: italic;
|
||||
font-family: 'Times New Roman', Times, serif;
|
||||
}
|
||||
|
||||
sup {
|
||||
/*background:lightpink;*/
|
||||
display: inline-block;
|
||||
font-size:0.92em;
|
||||
position: relative;
|
||||
top:-0.4em;
|
||||
letter-spacing: 0.001em;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.row.first {
|
||||
padding-bottom:1em;
|
||||
}
|
||||
|
||||
formula {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
padding: 0 1em;
|
||||
line-height: 3em;
|
||||
height: 3em;
|
||||
overflow: hidden;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.row.white formula {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
formula:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
formula.code {
|
||||
white-space: pre;
|
||||
font-family: "SFMono-Regular", Menlo, Consolas, Inconsolata, monospace;
|
||||
font-size:0.96em;
|
||||
}
|
||||
formula > * {
|
||||
margin: 0 0.2em 0 0.2em;
|
||||
}
|
||||
formula > const {
|
||||
margin-bottom: 0.11em;
|
||||
}
|
||||
formula > sup {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
||||
.samples {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
overflow: auto;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
.samples .sample {
|
||||
/*background: lightpink;*/
|
||||
color: #111;
|
||||
flex: 0 1 auto;
|
||||
outline: none;
|
||||
margin-right: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
.samples .sample .di {
|
||||
display: block;
|
||||
background-color: #ccc;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.samples .sample .di > span {
|
||||
display: block;
|
||||
background-color: #333;
|
||||
height: 100%;
|
||||
}
|
||||
.samples .sample .di.match > span {
|
||||
background-color: #0d3;
|
||||
}
|
||||
.samples .sample .di.unavailable {
|
||||
background-color: #eee;
|
||||
}
|
||||
.samples .sample .di.unavailable > span {
|
||||
visibility: hidden;
|
||||
}
|
||||
.samples .sample .info {
|
||||
display: block;
|
||||
font-size: 11px !important;
|
||||
line-height: 11px;
|
||||
margin-bottom: 9px;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
|
||||
.font-style-regular { font-weight:400 !important; font-style:normal !important; }
|
||||
.font-style-italic { font-weight:400 !important; font-style:italic !important; }
|
||||
.font-style-medium { font-weight:500 !important; font-style:normal !important; }
|
||||
.font-style-medium-italic { font-weight:500 !important; font-style:italic !important; }
|
||||
.font-style-bold { font-weight:700 !important; font-style:normal !important; }
|
||||
.font-style-bold-italic { font-weight:700 !important; font-style:italic !important; }
|
||||
.font-style-black { font-weight:900 !important; font-style:normal !important; }
|
||||
.font-style-black-italic { font-weight:900 !important; font-style:italic !important; }
|
||||
|
||||
.row.with-sidebar {
|
||||
padding: 0;
|
||||
}
|
||||
.row.with-sidebar > *:first-child {
|
||||
flex: 1 1 auto;
|
||||
padding: 50px 0 0 50px; /* note: samples have 50px right margin */
|
||||
}
|
||||
.row.with-sidebar > .sidebar {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
div.controls {
|
||||
box-sizing: border-box;
|
||||
width: 250px;
|
||||
max-width: 250px;
|
||||
flex: 0 0 auto;
|
||||
padding: 10px 0;
|
||||
border-left: 4px solid #f4f4f4;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
div.controls hr {
|
||||
border: none;
|
||||
height: 2px;
|
||||
background: #f4f4f4;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
div.controls hr.without-bottom-margin { margin-bottom: 0; }
|
||||
div.controls hr.without-top-margin { margin-top: 0; }
|
||||
div.controls hr.without-margins { margin: 0; }
|
||||
div.controls .control {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
height: 30px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
div.controls > h3 {
|
||||
margin: 0 16px;
|
||||
}
|
||||
div.controls > textarea {
|
||||
border: none;
|
||||
padding:16px;
|
||||
height: 400px;
|
||||
font-family: "SFMono-Regular", Menlo, Consolas, Inconsolata, monospace;
|
||||
outline: none;
|
||||
}
|
||||
div.controls .control > * {
|
||||
/*max-width: 50%;*/
|
||||
flex: 1 1 auto;
|
||||
margin:0;
|
||||
margin-right: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
div.controls .control > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
div.controls .control > select {
|
||||
min-width: 6em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
div.controls .control > input,
|
||||
div.controls .control > select {
|
||||
width: 0;
|
||||
outline: none;
|
||||
}
|
||||
div.controls .control > input[type="number"],
|
||||
div.controls .control > input[type="text"] {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
div.controls .control > input[type="number"] {
|
||||
max-width: 60px;
|
||||
-moz-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-webkit-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
}
|
||||
div.controls .control > input[type=number]::-webkit-inner-spin-button,
|
||||
div.controls .control > input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
div.controls .control > input[type="number"][readonly] {
|
||||
max-width: 40px;
|
||||
}
|
||||
div.controls .control > input.wide[type="number"] {
|
||||
max-width: 100%;
|
||||
}
|
||||
div.controls .control > input[type="range"] {
|
||||
/*max-width: 80%;*/
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
}
|
||||
div.controls .control > img.icon,
|
||||
div.controls .control > label {
|
||||
font-family: georgia, serif;
|
||||
font-style: italic;
|
||||
line-height: 16px;
|
||||
color: black;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
div.controls canvas {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.row.small-window {
|
||||
margin-top:0;
|
||||
padding-top:0;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 541px) {
|
||||
.small-window {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 540px) {
|
||||
|
||||
.row.with-sidebar {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.controls {
|
||||
display: none;
|
||||
}
|
||||
div.controls .graphplot,
|
||||
div.controls hr.without-top-margin,
|
||||
div.controls h3,
|
||||
div.controls #ideal-values
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row.with-sidebar {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
522
docs/dynmetrics/index.html
Normal file
522
docs/dynmetrics/index.html
Normal file
|
|
@ -0,0 +1,522 @@
|
|||
---
|
||||
layout: default
|
||||
title: Dynamic Metrics
|
||||
---
|
||||
{%
|
||||
|
||||
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 == "/dynmetrics/index.css" %}{%
|
||||
assign index_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/bindings.js" %}{%
|
||||
assign bindings_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/graphplot.js" %}{%
|
||||
assign graphplot_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
endif %}{%
|
||||
endfor
|
||||
|
||||
%}
|
||||
<link rel="stylesheet" href="index.css?v={{ index_css_v }}">
|
||||
<script src="{{url_root}}res/bindings.js?v={{ bindings_js_v }}"></script>
|
||||
<script src="{{url_root}}res/graphplot.js?v={{ graphplot_js_v }}"></script>
|
||||
|
||||
<div class="row first"><div>
|
||||
<h1>Dynamic Metrics</h1>
|
||||
<p>
|
||||
There's of course no absolute right or wrong when it comes to expressing
|
||||
yourself with typography, but Inter UI Dynamic Metrics provides guidelines
|
||||
for <em>good</em> typography.
|
||||
You simply provide the optical font size, and the tracking and leading
|
||||
(letter spacing and line height) will be calculated using the following
|
||||
formula:
|
||||
</p>
|
||||
<p>
|
||||
<formula>
|
||||
tracking =
|
||||
<const>a</const> + <const>b</const> ×
|
||||
<const>e</const><sup>(<const>c</const> × fontSize)</sup>
|
||||
</formula>
|
||||
<formula>
|
||||
leading = <const>l</const> × fontSize
|
||||
</formula>
|
||||
<formula>
|
||||
<const>e</const> ≈ <num>2.718</num>
|
||||
</formula>
|
||||
</p>
|
||||
<p class="small-window">
|
||||
<small>View this on a larger screen to enable interactive control.</small>
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<!-- <div class="row small-window"><div>
|
||||
Hello
|
||||
</div></div> -->
|
||||
|
||||
<div class="white full-width row with-sidebar">
|
||||
|
||||
<div class="samples">
|
||||
<p contenteditable class="sample">
|
||||
<span class="di"><span></span></span>
|
||||
<span class="info"
|
||||
title="size, tracking, (ideal tracking) — progress bar shows distance from ideal"
|
||||
>15 0.0 ( 0.0 )</span>
|
||||
Such a riot of sea and wind strews the whole extent of beach with whatever has been lost or thrown overboard, or torn out of sunken ships. Many a man has made a good week’s work in a single day by what he has found while walking along the Beach when the surf was down.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="sidebar controls">
|
||||
<div class="control">
|
||||
<label title="Number of ideal matches">ni</label>
|
||||
<input title="Number of ideal matches" type="number" readonly data-binding="ideal-count">
|
||||
<label title="Distance from ideal">di</label>
|
||||
<input title="Distance from ideal" type="number" class="wide" readonly data-binding="ideal-distance">
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Style" class="icon" src="../samples/icons/style.svg">
|
||||
<select data-binding="style">
|
||||
<option value="regular" default>Regular</option>
|
||||
<option value="italic">Italic</option>
|
||||
<option value="medium" default>Medium</option>
|
||||
<option value="medium-italic">Medium Italic</option>
|
||||
<option value="bold" default>Bold</option>
|
||||
<option value="bold-italic">Bold Italic</option>
|
||||
<option value="black" default>Black</option>
|
||||
<option value="black-italic">Black Italic</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Base tracking" class="icon" src="../samples/icons/letter-spacing.svg">
|
||||
<input type="range" min="-0.05" max="0.06" step="0.001" data-binding="base-tracking">
|
||||
<input type="number" min="-0.15" max="1" step="0.001" data-binding="base-tracking">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="control">
|
||||
<label title="Constant a">a</label>
|
||||
<input type="range" min="-0.05" max="0" step="0.001" data-binding="var-a">
|
||||
<input type="number" min="-0.05" max="0" step="0.0001" data-binding="var-a">
|
||||
</div>
|
||||
<div class="control">
|
||||
<label title="Constant b">b</label>
|
||||
<input type="range" min="0" max="1" step="0.01" data-binding="var-b">
|
||||
<input type="number" min="0" max="1" step="0.001" data-binding="var-b">
|
||||
</div>
|
||||
<div class="control">
|
||||
<label title="Constant c">c</label>
|
||||
<input type="range" min="-1" max="0" step="0.01" data-binding="var-c">
|
||||
<input type="number" min="-1" max="0" step="0.001" data-binding="var-c">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="control">
|
||||
<label title="Constant l controls line height">l</label>
|
||||
<input type="range" min="1" max="2" step="0.1" data-binding="var-l">
|
||||
<input type="number" min="1" max="2" step="0.1" data-binding="var-l">
|
||||
</div>
|
||||
<hr class="without-bottom-margin">
|
||||
<canvas class="graphplot">Canvas not Supported</canvas>
|
||||
<hr class="without-top-margin">
|
||||
<h3>Ideal values</h3>
|
||||
<textarea id="ideal-values"></textarea>
|
||||
<hr class="without-top-margin">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">(function(){
|
||||
|
||||
// internal variables that are user-controllable, but are not part of
|
||||
// Dynamic Metrics
|
||||
var baseTracking = 0
|
||||
var weightClass = 400
|
||||
|
||||
// Ideal values designed one by one, by hand.
|
||||
// font size => tracking
|
||||
var idealValues = {}
|
||||
var idealValuesList = []
|
||||
var idealValuesTextArea = $('textarea#ideal-values')
|
||||
|
||||
function setIdealValues(valueMap) {
|
||||
idealValues = valueMap
|
||||
idealValuesList = []
|
||||
Object.keys(idealValues).forEach(function(fontSize) {
|
||||
idealValuesList.push([fontSize, idealValues[fontSize]])
|
||||
})
|
||||
if (idealValuesTextArea.value == '') {
|
||||
idealValuesTextArea.value = idealValuesList.map(function(t){
|
||||
return t[0] + '\t' + t[1]
|
||||
}).join('\n')
|
||||
}
|
||||
}
|
||||
|
||||
function parseValues(s) {
|
||||
var values = {}
|
||||
s = s.replace(/^[\s\r\t\n]+|[\s\r\t\n]+$/g, '') // trim whitespace
|
||||
s.split(/\s*\r?\n\s*/).map(function(line) {
|
||||
var t = line.split(/\s+/)
|
||||
if (t.length == 2) {
|
||||
t[0] = parseInt(t[0])
|
||||
t[1] = parseFloat(t[1])
|
||||
values[t[0]] = t[1]
|
||||
}
|
||||
})
|
||||
return values
|
||||
}
|
||||
|
||||
setIdealValues({
|
||||
// set-2018-02-20
|
||||
6: 0.055,
|
||||
7: 0.044,
|
||||
8: 0.034,
|
||||
9: 0.024,
|
||||
10: 0.018,
|
||||
11: 0.012,
|
||||
12: 0.007,
|
||||
13: 0.003,
|
||||
14: 0.001,
|
||||
15: -0.002,
|
||||
16: -0.004,
|
||||
17: -0.006,
|
||||
18: -0.008,
|
||||
20: -0.01,
|
||||
24: -0.013,
|
||||
})
|
||||
|
||||
// setIdealValues({
|
||||
// // set-2018-02-19
|
||||
// 6: 0.059,
|
||||
// 7: 0.043,
|
||||
// 8: 0.032,
|
||||
// 9: 0.022,
|
||||
// 10: 0.014,
|
||||
// 11: 0.009,
|
||||
// 12: 0.004,
|
||||
// 13: 0,
|
||||
// 14: -0.003,
|
||||
// 15: -0.005,
|
||||
// 16: -0.0075,
|
||||
// 17: -0.0084,
|
||||
// 18: -0.0095,
|
||||
// 20: -0.012,
|
||||
// 24: -0.014,
|
||||
// })
|
||||
|
||||
// setIdealValues({
|
||||
// // set-2018-02-18
|
||||
// 6: 0.06,
|
||||
// 7: 0.04,
|
||||
// 8: 0.03,
|
||||
// 9: 0.02,
|
||||
// 10: 0.01,
|
||||
// 11: 0.005,
|
||||
// 12: 0.002,
|
||||
// 13: 0.001,
|
||||
// 14: 0,
|
||||
// 15: -0.002,
|
||||
// 16: -0.005,
|
||||
// 17: -0.007,
|
||||
// 18: -0.009,
|
||||
// 20: -0.011,
|
||||
// 24: -0.011,
|
||||
// })
|
||||
|
||||
|
||||
// Variables for constants involved in Dynamic Metrics
|
||||
var a = -0.013
|
||||
// -0.0119
|
||||
// -0.0101
|
||||
// -0.0092
|
||||
// -0.012
|
||||
// -0.013
|
||||
|
||||
var b = 0.23
|
||||
// 0.455
|
||||
// 0.421
|
||||
// 0.26
|
||||
// 0.23
|
||||
// 0.251
|
||||
|
||||
var c = -0.21
|
||||
// -0.29
|
||||
// -0.23
|
||||
// -0.21
|
||||
// -0.222
|
||||
|
||||
// a = -0.012; b = 0.23; c = -0.21; // di=0.002514 on set-2018-02-18
|
||||
// a = -0.013; b = 0.251; c = -0.222 // di=0.001742 on set-2018-02-18
|
||||
// a = -0.015; b = 0.283; c = -0.23; // di=0.00221 on set-2018-02-18
|
||||
// a = -0.0149; b = 0.298; c = -0.23; // di=0.000484 on set-2018-02-19
|
||||
a = -0.016; b = 0.21; c = -0.18; // di=0.000532 on set-2018-02-20
|
||||
|
||||
|
||||
// these have a short di, but stray far away from larger font sizes
|
||||
// a = -0.0077
|
||||
// b = 0.377
|
||||
|
||||
var l = 1.4
|
||||
|
||||
|
||||
// InterUIDynamicTracking takes the font size in points or pixels and returns
|
||||
// the compensating tracking in EM.
|
||||
//
|
||||
function InterUIDynamicTracking(fontSize, weightClass) {
|
||||
// if (!weightClass) { -- currently unused
|
||||
// weightClass = 400
|
||||
// }
|
||||
//
|
||||
// y = -0.01021241 + 0.3720623 * e ^ (-0.2808687 * x)
|
||||
// [6-35] 0.05877 .. -0.0101309 (13==0; stops growing around 30-35)
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
function InterUIDynamicLineHeight(fontSize, weightClass) {
|
||||
return Math.round(fontSize * l)
|
||||
}
|
||||
|
||||
|
||||
var NPOS = Number.MAX_SAFE_INTEGER
|
||||
|
||||
function Sample(fontSize) {
|
||||
this.rootEl = sampleTemplate.cloneNode(true)
|
||||
this.infoEl = $('.info', this.rootEl)
|
||||
this.diEl = $('.di', this.rootEl)
|
||||
this.diEl.classList.add('unavailable')
|
||||
this.style = this.rootEl.style
|
||||
this.maxBoxWidth = 0
|
||||
this.fontSize = 0
|
||||
this.tracking = 0
|
||||
this.lineHeight = 0
|
||||
this.idealTracking = NPOS
|
||||
this.matchesIdeal = false
|
||||
this.setFontSize(fontSize)
|
||||
this.render()
|
||||
}
|
||||
|
||||
Sample.prototype.idealDistance = function(fontSize) {
|
||||
// returns the distance from the ideal (or NPOS if no "ideal" data available)
|
||||
if (this.idealTracking == NPOS) {
|
||||
return NPOS
|
||||
}
|
||||
return (
|
||||
Math.max(this.tracking, this.idealTracking) -
|
||||
Math.min(this.tracking, this.idealTracking)
|
||||
)
|
||||
}
|
||||
|
||||
Sample.prototype.setFontSize = function(fontSize) {
|
||||
this.fontSize = fontSize
|
||||
this.tracking = baseTracking + InterUIDynamicTracking(fontSize, weightClass)
|
||||
this.lineHeight = InterUIDynamicLineHeight(fontSize, weightClass)
|
||||
this.maxBoxWidth = Math.round(fontSize * (this.tracking + 1) * 25)
|
||||
|
||||
var idealTracking = idealValues[this.fontSize]
|
||||
if (idealTracking === undefined) {
|
||||
if (this.idealTracking != NPOS) {
|
||||
this.diEl.classList.add('unavailable')
|
||||
}
|
||||
this.idealTracking = NPOS
|
||||
this.matchesIdeal = false
|
||||
} else {
|
||||
if (this.idealTracking == NPOS) {
|
||||
this.diEl.classList.remove('unavailable')
|
||||
}
|
||||
this.idealTracking = idealTracking
|
||||
// match to a precision of 3
|
||||
this.matchesIdeal = this.tracking.toFixed(3) == idealTracking.toFixed(3)
|
||||
var di = 1
|
||||
if (this.matchesIdeal) {
|
||||
this.diEl.classList.add('match')
|
||||
} else {
|
||||
this.diEl.classList.remove('match')
|
||||
di = 1 - Math.min(1, this.idealDistance() * 50)
|
||||
}
|
||||
this.diEl.firstChild.style.width = (di * this.maxBoxWidth) + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
Sample.prototype.render = function() {
|
||||
this.style.fontSize = this.fontSize + 'px'
|
||||
this.style.letterSpacing = this.tracking + 'em'
|
||||
this.style.lineHeight = this.lineHeight + 'px'
|
||||
|
||||
var SP = '\u00A0\u00A0\u00A0'
|
||||
this.infoEl.innerText = (
|
||||
this.fontSize +
|
||||
SP + this.tracking.toFixed(3) +
|
||||
// SP + this.lineHeight.toFixed(3) +
|
||||
(
|
||||
this.idealTracking != NPOS ? (
|
||||
SP + '( ' + this.idealTracking +
|
||||
(this.matchesIdeal ? ' \u2713' : '') +
|
||||
' )'
|
||||
) : ''
|
||||
)
|
||||
)
|
||||
|
||||
this.style.maxWidth = this.maxBoxWidth + 'px'
|
||||
}
|
||||
|
||||
|
||||
var bindings = new Bindings()
|
||||
var sampleTemplate
|
||||
var samples = [] // Sample[]
|
||||
var graph = new GraphPlot($('canvas.graphplot'))
|
||||
graph.setOrigin(-0.2, 0.8)
|
||||
graph.setScale(0.049, 5)
|
||||
|
||||
function addChildren(targetNode, children) {
|
||||
targetNode.style.visibility = 'hidden'
|
||||
var i = 0;
|
||||
for (; i < children.length; i++) {
|
||||
targetNode.appendChild(children[i])
|
||||
}
|
||||
targetNode.style.visibility = null
|
||||
}
|
||||
|
||||
function initSamples() {
|
||||
var samplesEl = $('.samples')
|
||||
sampleTemplate = $('.sample', samplesEl)
|
||||
samplesEl.removeChild(sampleTemplate)
|
||||
|
||||
// small and medium sizes
|
||||
var i, fontSize = 6, endFontSize = 16
|
||||
for (; fontSize <= endFontSize; fontSize++) {
|
||||
samples.push(new Sample(fontSize))
|
||||
}
|
||||
|
||||
// a few select large samples
|
||||
samples.push(new Sample(17))
|
||||
samples.push(new Sample(18))
|
||||
samples.push(new Sample(20))
|
||||
samples.push(new Sample(24))
|
||||
samples.push(new Sample(30))
|
||||
samples.push(new Sample(40))
|
||||
|
||||
// add to dom in one go
|
||||
addChildren(samplesEl, samples.map(function(s) { return s.rootEl }))
|
||||
}
|
||||
|
||||
|
||||
function updateSample(sample) {
|
||||
sample.setFontSize(sample.fontSize) // updates derived values
|
||||
sample.render()
|
||||
}
|
||||
|
||||
function updateSamples() {
|
||||
samples.forEach(updateSample)
|
||||
updateIdealMatches()
|
||||
updateGraphPlot()
|
||||
}
|
||||
|
||||
function updateIdealMatches() {
|
||||
// ideal-distance
|
||||
var idealCount = 0
|
||||
var distance = 0
|
||||
var ndistances = 0
|
||||
samples.forEach(function(sample) {
|
||||
if (sample.matchesIdeal) {
|
||||
idealCount++
|
||||
}
|
||||
var di = sample.idealDistance()
|
||||
if (di != NPOS) {
|
||||
distance += di
|
||||
ndistances++
|
||||
}
|
||||
})
|
||||
|
||||
distance = distance / ndistances
|
||||
|
||||
bindings.setValue('ideal-distance', distance.toFixed(6))
|
||||
bindings.setValue('ideal-count', idealCount)
|
||||
}
|
||||
|
||||
function updateGraphPlot() {
|
||||
graph.clear()
|
||||
graph.plotLine(idealValuesList, '#0d3')
|
||||
graph.plotf(function(x) {
|
||||
return InterUIDynamicTracking(x, weightClass)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
bindings.configure('base-tracking', 0, 'float', function (tracking) {
|
||||
baseTracking = tracking
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-a', a, 'float', function (v) {
|
||||
a = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-b', b, 'float', function (v) {
|
||||
b = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-c', c, 'float', function (v) {
|
||||
c = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-l', l, 'float', function (v) {
|
||||
l = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('ideal-count', 0, 'int', function (v) {})
|
||||
bindings.configure('ideal-distance', 0, 'float', function (v) {})
|
||||
|
||||
bindings.configure('style', null, null, function (style) {
|
||||
var cl = $('.samples').classList
|
||||
cl.remove('font-style-regular')
|
||||
cl.remove('font-style-italic')
|
||||
cl.remove('font-style-medium')
|
||||
cl.remove('font-style-medium-italic')
|
||||
cl.remove('font-style-bold')
|
||||
cl.remove('font-style-bold-italic')
|
||||
cl.remove('font-style-black')
|
||||
cl.remove('font-style-black-italic')
|
||||
cl.add('font-style-' + style)
|
||||
weightClass = (
|
||||
style.indexOf('black') != -1 ? 900 :
|
||||
style.indexOf('bold') != -1 ? 700 :
|
||||
style.indexOf('medium') != -1 ? 500 :
|
||||
400
|
||||
)
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
|
||||
bindings.bindAllInputs('.control input')
|
||||
bindings.bindAllInputs('.control select')
|
||||
|
||||
// double-click base tracking to reset
|
||||
$('input[type="range"][data-binding="base-tracking"]').addEventListener(
|
||||
'dblclick',
|
||||
function(ev) { bindings.setValue('base-tracking', 0) }
|
||||
)
|
||||
|
||||
// allow editing of ideal values
|
||||
idealValuesTextArea.addEventListener('input', function(ev) {
|
||||
setIdealValues(parseValues(idealValuesTextArea.value))
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
|
||||
// start
|
||||
initSamples()
|
||||
updateSamples()
|
||||
|
||||
})();</script>
|
||||
|
|
@ -1,39 +1,27 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Repertoire – Inter UI font family</title>
|
||||
---
|
||||
layout: default
|
||||
title: Glyphs
|
||||
---
|
||||
{%
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
capture url_root
|
||||
%}{% if site.safe == false %}/{% else %}/inter/{% endif
|
||||
%}{%
|
||||
endcapture %}{%
|
||||
|
||||
<meta property="og:title" content="Inter UI font family">
|
||||
<meta property="twitter:title" content="Inter UI font family">
|
||||
<meta property="description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="og:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:card" content="summary">
|
||||
<meta property="twitter:site" content="@rsms">
|
||||
<meta property="twitter:creator" content="@rsms">
|
||||
<meta property="og:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="twitter:image" content="https://rsms.me/inter/res/poster.png">
|
||||
for file in site.static_files %}{%
|
||||
assign _path = file.path | remove_first: "/inter" %}{%
|
||||
if _path == "/glyphs/glyphs.css" %}{%
|
||||
assign glyphs_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/glyphs/glyphs.js" %}{%
|
||||
assign glyphs_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
endif %}{%
|
||||
endfor
|
||||
|
||||
<meta property="fb:app_id" content="38027689216">
|
||||
<meta property="fb:admins" content="728642302">
|
||||
<meta property="og:url" content="https://rsms.me/inter/">
|
||||
<meta property="og:site_name" content="rsms.me">
|
||||
<meta property="og:type" content="product">
|
||||
<meta property="og:locale" content="en_US" />
|
||||
%}
|
||||
|
||||
<link rel="icon" type="image/png" href="../favicon.png" />
|
||||
|
||||
<link href="../inter-ui.css" rel="stylesheet">
|
||||
<link href="../index.css" rel="stylesheet">
|
||||
<link href="glyphs.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<script src="../index.js"></script>
|
||||
<div id="svgs">
|
||||
<link rel="stylesheet" href="glyphs.css?v={{ glyphs_css_v }}">
|
||||
<div id="svgs">
|
||||
<svg id="svg-A" xmlns="http://www.w3.org/2000/svg" width="176" height="348"><path d="M146 -76.8 L44.8 -76.8 L44.8 -54.8 L146 -54.8z M33.2 0 L94 -172.4 L96.4 -172.4 L157.2 0 L183.2 0 L108 -204.8 L82.4 -204.8 L7.2 0z" transform="translate(-7.2 281.6)"/></svg>
|
||||
<svg id="svg-AE" xmlns="http://www.w3.org/2000/svg" width="264" height="348"><path d="M142.4 -186 L144.8 -204.8 L127.2 -204.8 L6 0 L35.6 0z M164 -76.8 L60.4 -76.8 L60.4 -55.2 L164 -55.2z M269.2 -22 L168.4 -22 L168.4 0 L269.2 0z M164.8 -204.8 L140.4 -204.8 L148.8 0 L173.2 0z M249.6 -115.2 L162.8 -115.2 L162.8 -93.2 L249.6 -93.2z M260.8 -204.8 L160 -204.8 L160 -182.8 L260.8 -182.8z" transform="translate(-6 281.6)"/></svg>
|
||||
<svg id="svg-AEacute" xmlns="http://www.w3.org/2000/svg" width="264" height="348"><path d="M142.4 -186 L144.8 -204.8 L127.2 -204.8 L6 0 L35.6 0z M164 -76.8 L60.4 -76.8 L60.4 -55.2 L164 -55.2z M269.2 -22 L168.4 -22 L168.4 0 L269.2 0z M164.8 -204.8 L140.4 -204.8 L148.8 0 L173.2 0z M249.6 -115.2 L162.8 -115.2 L162.8 -93.2 L249.6 -93.2z M260.8 -204.8 L160 -204.8 L160 -182.8 L260.8 -182.8z M135.2 -223.2 L152.8 -223.2 L183.6 -264 L159.2 -264z" transform="translate(-6 281.6)"/></svg>
|
||||
|
|
@ -2222,37 +2210,34 @@
|
|||
<svg id="svg-zrthook" xmlns="http://www.w3.org/2000/svg" width="151" height="348"><path d="M112.8 -16.8 L112.8 19.2 C112.8 45.6 130.4 60 153.2 60 C157.6 60 163.2 59.6 166.8 58.4 L166.8 38 C164.8 38.8 161.2 38.8 159.2 38.8 C146.4 38.8 136.4 35.2 136.4 19.2 L136.4 -16.8z M136.4 -22 L28 -22 L28 0 L136.4 0z M134.4 -134.8 L134.4 -153.6 L120.8 -153.6 L17.6 -20 L17.6 0 L31.6 0z M122.4 -153.6 L16 -153.6 L16 -131.6 L122.4 -131.6z" transform="translate(-16 281.6)"/></svg>
|
||||
</div><!--END-SVGS don't remove this comment-->
|
||||
|
||||
<div class="row intro"><div>
|
||||
<h2 class="back"><a href="../">The Inter UI font family</a></h2>
|
||||
<h1><a href="./">Inter UI glyphs</a></h1>
|
||||
<p>
|
||||
This shows the complete set of glyphs in Inter UI Regular.
|
||||
You can zoom in and out by pressing
|
||||
<kbd>⌘</kbd><kbd>+</kbd> and
|
||||
<kbd>⌘</kbd><kbd>−</kbd> on your keyboard.
|
||||
Click on a glyph to see more details about it.
|
||||
</p>
|
||||
</div></div>
|
||||
<div class="row intro"><div>
|
||||
<h1><a href="./">Glyphs</a></h1>
|
||||
<p>
|
||||
This shows the complete set of glyphs in Inter UI Regular.
|
||||
You can zoom in and out by pressing
|
||||
<kbd>⌘</kbd><kbd>+</kbd> and
|
||||
<kbd>⌘</kbd><kbd>−</kbd> on your keyboard.
|
||||
Click on a glyph to see more details about it.
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<div id="glyphs">
|
||||
<div id="single-info" style="display:none">
|
||||
<ul>
|
||||
<li>Glyph name: <span class="name"></span></li>
|
||||
<li class="unicode">Unicode: <a><span class="unicodeCodePoint num"></span> <span class="unicodeName"></span></a></li>
|
||||
<li>Advance width: <span class="advanceWidth num"></span></li>
|
||||
<li>Left margin: <span class="marginLeft num"></span></li>
|
||||
<li>Right margin: <span class="marginRight num"></span></li>
|
||||
<li>Color mark: <span class="colorMark"> </span></li>
|
||||
<li><a class="svgFile">↓ Download SVG file</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="glyphs">
|
||||
<div id="single-info" style="display:none">
|
||||
<ul>
|
||||
<li>Glyph name: <span class="name"></span></li>
|
||||
<li class="unicode">Unicode: <a><span class="unicodeCodePoint num"></span> <span class="unicodeName"></span></a></li>
|
||||
<li>Advance width: <span class="advanceWidth num"></span></li>
|
||||
<li>Left margin: <span class="marginLeft num"></span></li>
|
||||
<li>Right margin: <span class="marginRight num"></span></li>
|
||||
<li>Color mark: <span class="colorMark"> </span></li>
|
||||
<li><a class="svgFile">↓ Download SVG file</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row kerning"><div>
|
||||
<h2 id="kerning"><a href="#kerning">Kerning</a></h2>
|
||||
<div id="kerning-list"></div>
|
||||
</div></div>
|
||||
<div class="row kerning"><div>
|
||||
<h2 id="kerning"><a href="#kerning">Kerning</a></h2>
|
||||
<div id="kerning-list"></div>
|
||||
</div></div>
|
||||
|
||||
<script src="glyphs.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<script src="glyphs.js?v={{ glyphs_js_v }}"></script>
|
||||
|
|
|
|||
606
docs/index.html
606
docs/index.html
|
|
@ -1,360 +1,326 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Inter UI font family</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta property="og:title" content="Inter UI font family">
|
||||
<meta property="twitter:title" content="Inter UI font family">
|
||||
<meta property="description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="og:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:card" content="summary">
|
||||
<meta property="twitter:site" content="@rsms">
|
||||
<meta property="twitter:creator" content="@rsms">
|
||||
<meta property="og:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="twitter:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="fb:app_id" content="38027689216">
|
||||
<meta property="og:url" content="https://rsms.me/inter/">
|
||||
<meta property="og:site_name" content="rsms.me">
|
||||
<meta property="og:type" content="product">
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link href="inter-ui.css?v=2.5" rel="stylesheet">
|
||||
<link href="index.css?v=5" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<div class="row menu">
|
||||
<ul class="menu">
|
||||
<li class="home"><a href="../">Inter UI</a></li>
|
||||
<li><a class="download-link"
|
||||
href="https://github.com/rsms/inter/releases/latest/"
|
||||
>Download</a></li>
|
||||
<li><a href="samples/">Samples</a></li>
|
||||
<li><a href="lab/">Playground</a></li>
|
||||
<li><a href="https://github.com/rsms/inter/">Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row"><div>
|
||||
<h1>The Inter UI font family</h1>
|
||||
<p>
|
||||
Inter UI is a typeface specially designed for user interfaces
|
||||
with focus on high legibility of small-to-medium sized text on computer screens.
|
||||
</p>
|
||||
<p>
|
||||
The family features a tall x-height to aid in readability of mixed-case and
|
||||
lower-case text. Several OpenType features are provided as well,
|
||||
like contextual alternates that adjusts punctuation depending on the shape of
|
||||
surrounding glyphs, slashed zero for when you need to disambiguate "0" from "o",
|
||||
tabular numbers, etc.
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<div class="row"><div>
|
||||
<h1>The Inter UI font family</h1>
|
||||
<p>
|
||||
Inter UI is a typeface specially designed for user interfaces
|
||||
with focus on high legibility of small-to-medium sized text on computer screens.
|
||||
</p>
|
||||
<p>
|
||||
The family features a tall x-height to aid in readability of mixed-case and
|
||||
lower-case text. Several OpenType features are provided as well,
|
||||
like contextual alternates that adjusts punctuation depending on the shape of
|
||||
surrounding glyphs, slashed zero for when you need to disambiguate "0" from "o",
|
||||
tabular numbers, etc.
|
||||
</p>
|
||||
</div></div>
|
||||
<div class="row white" style="padding-bottom:0"><div>
|
||||
<p id="samples" class="samples items sample-images">
|
||||
<a href="samples/" class="plain"><img src="samples/img/01.png" srcset="samples/img/01@2x.png 2x" width="888"></a>
|
||||
</p>
|
||||
<p style="text-align:center">
|
||||
<a href="samples/" class="plain">More samples -></a>
|
||||
<br><br>
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<div class="row white" style="padding-bottom:0"><div>
|
||||
<p id="samples" class="samples items">
|
||||
<a href="samples/" class="plain"><img src="samples/img/01.png" srcset="samples/img/01@2x.png 2x" width="888"></a>
|
||||
</p>
|
||||
<p style="text-align:center">
|
||||
<a href="samples/" class="plain">More samples -></a>
|
||||
<br><br>
|
||||
</p>
|
||||
</div></div>
|
||||
<div class="row dark"><div>
|
||||
|
||||
<div class="row dark"><div>
|
||||
<h2><a id="usage" href="#usage">How do I use it?</a></h2>
|
||||
<p>
|
||||
Using the font is as easy as
|
||||
<a class="download-link" href="https://github.com/rsms/inter/releases/latest/">download & installing</a> locally on your computer.
|
||||
</p>
|
||||
<p>
|
||||
You're free to bundle copies of Inter UI with your software, even if it's
|
||||
commercial and you charge money for your software. Inter UI can also be used
|
||||
on the web by either hosting the font files yourself or by including this CSS:
|
||||
</p>
|
||||
<code>@import url('https://rsms.me/inter/inter-ui.css');</code>
|
||||
<p>Use the following CSS rules to specify the Inter UI family:</p>
|
||||
<code>font-family: 'Inter UI', sans-serif;</code>
|
||||
|
||||
<h2><a id="usage" href="#usage">How do I use it?</a></h2>
|
||||
<p>
|
||||
Using the font is as easy as
|
||||
<a class="download-link" href="https://github.com/rsms/inter/releases/latest/">download & installing</a> locally on your computer.
|
||||
</p>
|
||||
<p>
|
||||
You're free to bundle copies of Inter UI with your software, even if it's
|
||||
commercial and you charge money for your software. Inter UI can also be used
|
||||
on the web by either hosting the font files yourself or by including this CSS:
|
||||
</p>
|
||||
<code>@import url('https://rsms.me/inter/inter-ui.css');</code>
|
||||
<p>Use the following CSS rules to specify the Inter UI family:</p>
|
||||
<code>font-family: 'Inter UI', sans-serif;</code>
|
||||
<p> </p>
|
||||
|
||||
<p> </p>
|
||||
<h2><a href="{{url_root}}dynmetrics/">Dynamic Metrics</a></h2>
|
||||
<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.
|
||||
<a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics —></a>
|
||||
</p>
|
||||
|
||||
<h2><a id="free" href="#free">How much does it cost?</a></h2>
|
||||
<p>
|
||||
Inter UI is a <a href="https://github.com/rsms/inter">free and open source</a> font family. You are free to use this font in almost any way imaginable.
|
||||
Refer to the <a href="https://choosealicense.com/licenses/ofl-1.1/">SIL Open Font License 1.1</a> for exact details on what the conditions and restrictions are.
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
</div></div>
|
||||
<h2><a id="free" href="#free">How much does it cost?</a></h2>
|
||||
<p>
|
||||
Inter UI is a <a href="https://github.com/rsms/inter">free and open source</a> font family. You are free to use this font in almost any way imaginable.
|
||||
Refer to the <a href="https://choosealicense.com/licenses/ofl-1.1/">SIL Open Font License 1.1</a> for exact details on what the conditions and restrictions are.
|
||||
</p>
|
||||
|
||||
<div class="row"><div>
|
||||
<p>
|
||||
There are currently four <a id="weights" href="#weights">weights</a>
|
||||
</p>
|
||||
<img src="res/weights-and-styles.svg" style="opacity:0.76;width:100%;display:block;margin:2em 0 3em 0">
|
||||
<h2><a id="features" href="#features">Features</a></h2>
|
||||
<boxes>
|
||||
<box>
|
||||
<h3>Contextual alternates (<q title='OpenType feature ID'>calt</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in>12<em>:</em>34, FE<em>—</em>X</in><to></to><out>12:34, FE—X</out></r>
|
||||
<r><in>4<em>.</em>2</in><to></to><out>4.2</out></r>
|
||||
<r><in>SFO <em>-></em> STO</in><to></to><out>SFO -> STO</out></r>
|
||||
<r><in>IIA <em>—></em> OGG</in><to></to><out>IIA —> OGG</out></r>
|
||||
<r><in>M<em>@</em>N m@n</in><to></to><out>M@N m@n</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
</div></div>
|
||||
|
||||
<box>
|
||||
<h3>Tabular numbers (<q title='OpenType feature ID'>tnum</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in><em>1</em>23456<em>7</em>890</in><to></to><out class="tnum">1234567890</out></r>
|
||||
<r><in>1131711<em> </em></in><to></to><out class="tnum">1131711<em> </em></out></r>
|
||||
<r><in>0040900<em> </em></in><to></to><out class="tnum">0040900<em> </em></out></r>
|
||||
<r><in>11:31,711<em> </em></in><to></to><out class="tnum">11:31,711<em> </em></out></r>
|
||||
<r><in>00:40.900<em> </em></in><to></to><out class="tnum">00:40.900<em> </em></out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
<div class="row"><div>
|
||||
<p>
|
||||
There are currently four <a id="weights" href="#weights">weights</a>
|
||||
</p>
|
||||
<img src="res/weights-and-styles.svg" style="opacity:0.76;width:100%;display:block;margin:2em 0 3em 0">
|
||||
<h2><a id="features" href="#features">Features</a></h2>
|
||||
<boxes>
|
||||
<box>
|
||||
<h3>Contextual alternates (<q title='OpenType feature ID'>calt</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in>12<em>:</em>34, FE<em>—</em>X</in><to></to><out>12:34, FE—X</out></r>
|
||||
<r><in>4<em>.</em>2</in><to></to><out>4.2</out></r>
|
||||
<r><in>SFO <em>-></em> STO</in><to></to><out>SFO -> STO</out></r>
|
||||
<r><in>IIA <em>—></em> OGG</in><to></to><out>IIA —> OGG</out></r>
|
||||
<r><in>M<em>@</em>N m@n</in><to></to><out>M@N m@n</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
<box>
|
||||
<h3>Slashed zero (<q title='OpenType feature ID'>zero</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in><em>0</em>123</in><to></to><out class="zero">0123</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
<box>
|
||||
<h3>Tabular numbers (<q title='OpenType feature ID'>tnum</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in><em>1</em>23456<em>7</em>890</in><to></to><out class="tnum">1234567890</out></r>
|
||||
<r><in>1131711<em> </em></in><to></to><out class="tnum">1131711<em> </em></out></r>
|
||||
<r><in>0040900<em> </em></in><to></to><out class="tnum">0040900<em> </em></out></r>
|
||||
<r><in>11:31,711<em> </em></in><to></to><out class="tnum">11:31,711<em> </em></out></r>
|
||||
<r><in>00:40.900<em> </em></in><to></to><out class="tnum">00:40.900<em> </em></out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
<box>
|
||||
<h3>Fractions (<q title='OpenType feature ID'>frac</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>1/3</em> <em>22/9</em> <em>3/4/5</em></in>
|
||||
<to></to><out class="frac">1/3 22/9 3/4/5</out>
|
||||
</r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
<box>
|
||||
<h3>Slashed zero (<q title='OpenType feature ID'>zero</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r><in><em>0</em>123</in><to></to><out class="zero">0123</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
<box>
|
||||
<h3>Stylistic set 1: Alternate digits (<q title='OpenType feature ID'>ss01</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>1</em>23<em>4</em>5<em>6</em>78<em>9</em>0</in>
|
||||
<to></to><out class="ss01">1234567890</out>
|
||||
</r>
|
||||
<r><in><em>1</em></in><to></to><out class="ss01">1</out></r>
|
||||
<r><in><em>4</em></in><to></to><out class="ss01">4</out></r>
|
||||
<r><in><em>6</em></in><to></to><out class="ss01">6</out></r>
|
||||
<r><in><em>9</em></in><to></to><out class="ss01">9</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
<box>
|
||||
<h3>Fractions (<q title='OpenType feature ID'>frac</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>1/3</em> <em>22/9</em> <em>3/4/5</em></in>
|
||||
<to></to><out class="frac">1/3 22/9 3/4/5</out>
|
||||
</r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
<box>
|
||||
<h3>Case alternates (<q title='OpenType feature ID'>case</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>(</em>Hello<em>)</em> <em>[</em>World<em>]</em> <em>{</em>9000<em>}</em></in>
|
||||
<to></to><out class="case">(Hello) [World] {9000}</out>
|
||||
</r>
|
||||
<r><in>SCHOOL <em>@</em> RUN</in><to></to><out class="case">SCHOOL @ RUN</out></r>
|
||||
<r><in>3 <em>+</em> 9 <em>=</em> 12 <em>*</em> 1</in><to></to><out class="case">3 + 9 = 12 * 1</out></r>
|
||||
<r><in><em>*</em> <em>+</em> <em>÷</em> <em>±</em> <em>×</em> <em>=</em> <em>≠</em> <em>•</em></in><to></to><out class="case">* + ÷ ± × = ≠ •</out></r>
|
||||
<r><in><em>→</em> <em>←</em> <em>⟶</em> <em>⟵</em> <em>−</em> <em>-</em> <em>–</em> <em>—</em> <em>:</em></in><to></to><out class="case">→ ← ⟶ ⟵ − - – — :</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
<box>
|
||||
<h3>Stylistic set 1: Alternate digits (<q title='OpenType feature ID'>ss01</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>1</em>23<em>4</em>5<em>6</em>78<em>9</em>0</in>
|
||||
<to></to><out class="ss01">1234567890</out>
|
||||
</r>
|
||||
<r><in><em>1</em></in><to></to><out class="ss01">1</out></r>
|
||||
<r><in><em>4</em></in><to></to><out class="ss01">4</out></r>
|
||||
<r><in><em>6</em></in><to></to><out class="ss01">6</out></r>
|
||||
<r><in><em>9</em></in><to></to><out class="ss01">9</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
</boxes>
|
||||
<box>
|
||||
<h3>Case alternates (<q title='OpenType feature ID'>case</q>)</h3>
|
||||
<tablex><t>
|
||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||
<r>
|
||||
<in><em>(</em>Hello<em>)</em> <em>[</em>World<em>]</em> <em>{</em>9000<em>}</em></in>
|
||||
<to></to><out class="case">(Hello) [World] {9000}</out>
|
||||
</r>
|
||||
<r><in>SCHOOL <em>@</em> RUN</in><to></to><out class="case">SCHOOL @ RUN</out></r>
|
||||
<r><in>3 <em>+</em> 9 <em>=</em> 12 <em>*</em> 1</in><to></to><out class="case">3 + 9 = 12 * 1</out></r>
|
||||
<r><in><em>*</em> <em>+</em> <em>÷</em> <em>±</em> <em>×</em> <em>=</em> <em>≠</em> <em>•</em></in><to></to><out class="case">* + ÷ ± × = ≠ •</out></r>
|
||||
<r><in><em>→</em> <em>←</em> <em>⟶</em> <em>⟵</em> <em>−</em> <em>-</em> <em>–</em> <em>—</em> <em>:</em></in><to></to><out class="case">→ ← ⟶ ⟵ − - – — :</out></r>
|
||||
</t></tablex>
|
||||
</box>
|
||||
|
||||
<p>
|
||||
Also includes some
|
||||
Localized Forms (<q title='OpenType feature ID'>locl</q>),
|
||||
Numerators (<q title='OpenType feature ID'>numr</q>) and
|
||||
Denominators (<q title='OpenType feature ID'>dnom</q>).
|
||||
</p>
|
||||
</boxes>
|
||||
|
||||
<p> </p>
|
||||
<p>
|
||||
Also includes some
|
||||
Localized Forms (<q title='OpenType feature ID'>locl</q>),
|
||||
Numerators (<q title='OpenType feature ID'>numr</q>) and
|
||||
Denominators (<q title='OpenType feature ID'>dnom</q>).
|
||||
</p>
|
||||
|
||||
<h2 class="banner"><a href="glyphs/">Browse all glyphs -></a></h2>
|
||||
</div></div>
|
||||
<p> </p>
|
||||
|
||||
<div class="row-divider"></div>
|
||||
<h2 class="banner"><a href="glyphs/">Browse all glyphs -></a></h2>
|
||||
</div></div>
|
||||
|
||||
<div class="row"><div>
|
||||
<h2><a id="story" href="#story">The story behind Inter UI</a></h2>
|
||||
<p>
|
||||
Inter UI started out in late 2016 as an experiment to build a perfectly
|
||||
pixel-fitting font at a specific small size (11px.) The idea was that
|
||||
by crafting a font in a particular way, with a particular coordinate system
|
||||
(Units Per EM), and for a particular target rasterization size (11), it would
|
||||
be possible to get the best of both sharpness and readability.
|
||||
</p>
|
||||
<p>
|
||||
However after a few months of using an early version of Inter UI, it dawned
|
||||
on everyone exposed to the test that this approach had some serious real-world
|
||||
problems. Most notably that it was really hard to read longer text. Because of
|
||||
the pixel-aligning nature of that approach, the font took an almost
|
||||
<a href="https://www.figma.com/file/HPqDViSCB8fAWuxaV2ousFMv">mono-spaced appearance</a>,
|
||||
making it really easy to read numbers, punctuation and very short
|
||||
words, but eye-straining to read anything longer.
|
||||
</p>
|
||||
<p>
|
||||
The project was rebooted with a different approach, sticking with the
|
||||
specific UPM, but crafting glyphs and kerning in a way that made for
|
||||
more variation in the rhythm and smoother vertical and horizontal stems.
|
||||
As Inter UI was being developed, it was tested on an internal version of
|
||||
<a href="https://www.figma.com/">Figma</a>—where the author of Inter UI works as a designer—and slowly improved upon based on experience and feedback.
|
||||
</p>
|
||||
<div class="row-divider"></div>
|
||||
|
||||
<p> </p>
|
||||
<div class="row"><div>
|
||||
<h2><a id="story" href="#story">The story behind Inter UI</a></h2>
|
||||
<p>
|
||||
Inter UI started out in late 2016 as an experiment to build a perfectly
|
||||
pixel-fitting font at a specific small size (11px.) The idea was that
|
||||
by crafting a font in a particular way, with a particular coordinate system
|
||||
(Units Per EM), and for a particular target rasterization size (11), it would
|
||||
be possible to get the best of both sharpness and readability.
|
||||
</p>
|
||||
<p>
|
||||
However after a few months of using an early version of Inter UI, it dawned
|
||||
on everyone exposed to the test that this approach had some serious real-world
|
||||
problems. Most notably that it was really hard to read longer text. Because of
|
||||
the pixel-aligning nature of that approach, the font took an almost
|
||||
<a href="https://www.figma.com/file/HPqDViSCB8fAWuxaV2ousFMv">mono-spaced appearance</a>,
|
||||
making it really easy to read numbers, punctuation and very short
|
||||
words, but eye-straining to read anything longer.
|
||||
</p>
|
||||
<p>
|
||||
The project was rebooted with a different approach, sticking with the
|
||||
specific UPM, but crafting glyphs and kerning in a way that made for
|
||||
more variation in the rhythm and smoother vertical and horizontal stems.
|
||||
As Inter UI was being developed, it was tested on an internal version of
|
||||
<a href="https://www.figma.com/">Figma</a>—where the author of Inter UI works as a designer—and slowly improved upon based on experience and feedback.
|
||||
</p>
|
||||
|
||||
<h2><a id="status" href="#status">Current status & usability</a></h2>
|
||||
<p>
|
||||
Inter UI works great for English-language text, and pretty well for other
|
||||
Latin and Cyrillic languages. There's still a lot of work to be done, and
|
||||
<a href="https://github.com/rsms/inter/blob/master/CONTRIBUTING.md">contributions are warmly welcomed</a>. The playground contains <a href="lab/?sample=Body%20text%201&size=16">a lot of samples</a>, including some common <a href="lab/?sample=Kerning%20body%20multi-lang&size=16">non English-language words in the playground.</a>
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
<p>
|
||||
Please refer to the <a href="glyphs/">glyph repertoire</a>
|
||||
for an overview of currently-available glyphs and their quality.
|
||||
</p>
|
||||
<h2><a id="status" href="#status">Current status & usability</a></h2>
|
||||
<p>
|
||||
Inter UI works great for English-language text, and pretty well for other
|
||||
Latin and Cyrillic languages. There's still a lot of work to be done, and
|
||||
<a href="https://github.com/rsms/inter/blob/master/CONTRIBUTING.md">contributions are warmly welcomed</a>. The playground contains <a href="lab/?sample=Body%20text%201&size=16">a lot of samples</a>, including some common <a href="lab/?sample=Kerning%20body%20multi-lang&size=16">non English-language words in the playground.</a>
|
||||
</p>
|
||||
|
||||
<p> </p>
|
||||
<p>
|
||||
Please refer to the <a href="glyphs/">glyph repertoire</a>
|
||||
for an overview of currently-available glyphs and their quality.
|
||||
</p>
|
||||
|
||||
<h2><a id="faq" href="#faq">FAQ</a></h2>
|
||||
<ul class="faq">
|
||||
<p> </p>
|
||||
|
||||
<li class="q" id="faq-using-features">
|
||||
How do I enable and disable font features?
|
||||
</li>
|
||||
<li class="a">
|
||||
In web browsers you'll want to use
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings"><q>font-feature-settings</q></a>.
|
||||
In Figma you can access features via the
|
||||
<a href="https://help.figma.com/text/opentype-features">Advanced Typography panel.</a>
|
||||
In Illustrator, Photoshop and friends, you can access features via the
|
||||
<a href="https://helpx.adobe.com/illustrator/using/special-characters.html#opentype_panel_overview">Characters and OpenType panels.</a>
|
||||
Sketch doesn't provide a UI for configuring font features, but there's
|
||||
<a href="https://sketchtalk.io/discussion/comment/1478/#Comment_1478">a workaround using macOS's native font UI.</a>
|
||||
</li>
|
||||
<h2><a id="faq" href="#faq">FAQ</a></h2>
|
||||
<ul class="faq">
|
||||
|
||||
<li class="q" id="faq-unhinted-vs-hinted">
|
||||
What is the difference between "unhinted" and "hinted" font files?
|
||||
</li>
|
||||
<li class="a">
|
||||
The font files in the "hinted" folders have additional data in them
|
||||
for assisting
|
||||
<a href="https://en.wikipedia.org/wiki/ClearType">ClearType</a>,
|
||||
the text rasterizer used by Microsoft Windows (and some Linux distributions.)
|
||||
You want to use the "hinted" fonts only if you are targeting Windows users
|
||||
<em>and</em> prefer the different look of these "hinted" fonts.
|
||||
Additionally, hinting data makes the font files larger, so if you are
|
||||
using Inter UI on websites, the extra size of these files is another
|
||||
consideration to make.
|
||||
<a href="https://www.typotheque.com/articles/hinting">
|
||||
This article explains hinting at a greater length.</a>
|
||||
</li>
|
||||
<li class="q" id="faq-using-features">
|
||||
How do I enable and disable font features?
|
||||
</li>
|
||||
<li class="a">
|
||||
In web browsers you'll want to use
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings"><q>font-feature-settings</q></a>.
|
||||
In Figma you can access features via the
|
||||
<a href="https://help.figma.com/text/opentype-features">Advanced Typography panel.</a>
|
||||
In Illustrator, Photoshop and friends, you can access features via the
|
||||
<a href="https://helpx.adobe.com/illustrator/using/special-characters.html#opentype_panel_overview">Characters and OpenType panels.</a>
|
||||
Sketch doesn't provide a UI for configuring font features, but there's
|
||||
<a href="https://sketchtalk.io/discussion/comment/1478/#Comment_1478">a workaround using macOS's native font UI.</a>
|
||||
</li>
|
||||
|
||||
<li class="q" id="faq-unhinted-vs-hinted">
|
||||
What is the difference between "unhinted" and "hinted" font files?
|
||||
</li>
|
||||
<li class="a">
|
||||
The font files in the "hinted" folders have additional data in them
|
||||
for assisting
|
||||
<a href="https://en.wikipedia.org/wiki/ClearType">ClearType</a>,
|
||||
the text rasterizer used by Microsoft Windows (and some Linux distributions.)
|
||||
You want to use the "hinted" fonts only if you are targeting Windows users
|
||||
<em>and</em> prefer the different look of these "hinted" fonts.
|
||||
Additionally, hinting data makes the font files larger, so if you are
|
||||
using Inter UI on websites, the extra size of these files is another
|
||||
consideration to make.
|
||||
<a href="https://www.typotheque.com/articles/hinting">
|
||||
This article explains hinting at a greater length.</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="q" id="faq-cdn">
|
||||
How reliable are the fonts served from rsms.me/inter? Is it on a CDN?
|
||||
</li>
|
||||
<li class="a">
|
||||
rsms.me/inter is backed by GitHub's server network and distributed
|
||||
globally on the CloudFlare CDN, making usage of
|
||||
<q>https://rsms.me/inter/inter-ui.css</q> and associated font
|
||||
files very reliable and fast throughout the world.
|
||||
</li>
|
||||
<li class="q" id="faq-cdn">
|
||||
How reliable are the fonts served from rsms.me/inter? Is it on a CDN?
|
||||
</li>
|
||||
<li class="a">
|
||||
rsms.me/inter is backed by GitHub's server network and distributed
|
||||
globally on the CloudFlare CDN, making usage of
|
||||
<q>https://rsms.me/inter/inter-ui.css</q> and associated font
|
||||
files very reliable and fast throughout the world.
|
||||
</li>
|
||||
|
||||
<li class="q" id="faq-contribute">
|
||||
Can I help with improving Inter UI?
|
||||
</li>
|
||||
<li class="a">
|
||||
Yes you can! Inter UI is an open-source project, meaning the source
|
||||
code—or "source design" if you will—that is used to build the font files
|
||||
<a href="https://github.com/rsms/inter">are freely available</a> to improve upon.
|
||||
Font making requires a fair bit of technical work and
|
||||
depending on what you'd like to do, some things might be more fun
|
||||
depending on your technical skills.
|
||||
The <a href="https://github.com/rsms/inter/blob/master/CONTRIBUTING.md">"Contributing" document</a> is a great place to start. The document outlines where
|
||||
you can have the biggest impact, how things are setup and how to get
|
||||
started.
|
||||
</li>
|
||||
<li class="q" id="faq-contribute">
|
||||
Can I help with improving Inter UI?
|
||||
</li>
|
||||
<li class="a">
|
||||
Yes you can! Inter UI is an open-source project, meaning the source
|
||||
code—or "source design" if you will—that is used to build the font files
|
||||
<a href="https://github.com/rsms/inter">are freely available</a> to improve upon.
|
||||
Font making requires a fair bit of technical work and
|
||||
depending on what you'd like to do, some things might be more fun
|
||||
depending on your technical skills.
|
||||
The <a href="https://github.com/rsms/inter/blob/master/CONTRIBUTING.md">"Contributing" document</a> is a great place to start. The document outlines where
|
||||
you can have the biggest impact, how things are setup and how to get
|
||||
started.
|
||||
</li>
|
||||
|
||||
<li class="q" id="faq-start-date">
|
||||
This website claims work started in 2016, but the git repository's log says it started later?
|
||||
</li>
|
||||
<li class="a">
|
||||
Inter UI was developed in an a private, internal git repository
|
||||
starting in November 2016, prior to being published on August 22, 2017.
|
||||
Between November 2016 and August 2017, there were
|
||||
<num>2 990 150</num> line edits made across 247 versions.
|
||||
The reason the public GitHub repository does not reflect this is the
|
||||
fact that the project was initially only internal at the company where
|
||||
the author works and had some sensitive information "checked in",
|
||||
like AWS server details and internal author identity in
|
||||
all commit messages. Maybe one day we can write an elaborate git
|
||||
filter-branch program and convert the filter the old repository to make
|
||||
it public, but what would be the point of that? :—)
|
||||
</li>
|
||||
<li class="q" id="faq-start-date">
|
||||
This website claims work started in 2016, but the git repository's log says it started later?
|
||||
</li>
|
||||
<li class="a">
|
||||
Inter UI was developed in an a private, internal git repository
|
||||
starting in November 2016, prior to being published on August 22, 2017.
|
||||
Between November 2016 and August 2017, there were
|
||||
<num>2 990 150</num> line edits made across 247 versions.
|
||||
The reason the public GitHub repository does not reflect this is the
|
||||
fact that the project was initially only internal at the company where
|
||||
the author works and had some sensitive information "checked in",
|
||||
like AWS server details and internal author identity in
|
||||
all commit messages. Maybe one day we can write an elaborate git
|
||||
filter-branch program and convert the filter the old repository to make
|
||||
it public, but what would be the point of that? :—)
|
||||
</li>
|
||||
|
||||
<li class="q" id="faq-contact">
|
||||
I've made a cool thing that uses Inter UI, can I share it with you?
|
||||
<dem>or</dem>
|
||||
</li>
|
||||
<li class="q">
|
||||
I have a different question
|
||||
</li>
|
||||
<li class="a">
|
||||
Reach out on <a href="https://twitter.com/rsms">Twitter (@rsms)</a> or over <a href="mailto:rasmus@notion.se">email</a>
|
||||
</li>
|
||||
<li class="q" id="faq-contact">
|
||||
I've made a cool thing that uses Inter UI, can I share it with you?
|
||||
<dem>or</dem>
|
||||
</li>
|
||||
<li class="q">
|
||||
I have a different question
|
||||
</li>
|
||||
<li class="a">
|
||||
Reach out on <a href="https://twitter.com/rsms">Twitter (@rsms)</a> or over <a href="mailto:rasmus@notion.se">email</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
</div></div>
|
||||
</div></div>
|
||||
|
||||
|
||||
<div class="row"><div>
|
||||
— <a href="https://twitter.com/rsms" class="plain">@rsms</a>
|
||||
</div></div>
|
||||
<div class="row"><div>
|
||||
— <a href="https://twitter.com/rsms" class="plain">@rsms</a>
|
||||
</div></div>
|
||||
|
||||
<script src="index.js?v=2"></script>
|
||||
<script>
|
||||
(function(){
|
||||
<script>(function(){
|
||||
|
||||
// FAQ anchors
|
||||
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)
|
||||
id = e.id
|
||||
if (id) {
|
||||
a = document.createElement('a')
|
||||
// a.id = id
|
||||
a.href = '#' + id
|
||||
a.className = 'plain'
|
||||
a.innerHTML = e.innerHTML
|
||||
e.innerText = ''
|
||||
e.appendChild(a)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
// FAQ anchors
|
||||
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)
|
||||
id = e.id
|
||||
if (id) {
|
||||
a = document.createElement('a')
|
||||
// a.id = id
|
||||
a.href = '#' + id
|
||||
a.className = 'plain'
|
||||
a.innerHTML = e.innerHTML
|
||||
e.innerText = ''
|
||||
e.appendChild(a)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
})();</script>
|
||||
|
|
|
|||
138
docs/index.js
138
docs/index.js
|
|
@ -1,138 +0,0 @@
|
|||
var isMac = false
|
||||
|
||||
function $$(query, el) {
|
||||
return [].slice.call((el || document).querySelectorAll(query))
|
||||
}
|
||||
|
||||
function $(query, el) {
|
||||
return (el || document).querySelector(query)
|
||||
}
|
||||
|
||||
// fetchjson(url string, cb (err Error, d Object)->nil)
|
||||
//
|
||||
var fetchjson = (
|
||||
typeof window.fetch == 'function' ? (
|
||||
function _fetchjson(url, cb) {
|
||||
return window.fetch(url)
|
||||
.then(function(r) { return r.json() })
|
||||
.then(function(data) { cb(null, data) })
|
||||
.catch(cb)
|
||||
}
|
||||
) :
|
||||
function _fetchjson(url, cb) {
|
||||
var r = new XMLHttpRequest()
|
||||
r.addEventListener("load", function(){
|
||||
try {
|
||||
cb(null, JSON.parse(r.responseText))
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
})
|
||||
r.open("GET", url)
|
||||
r.send()
|
||||
}
|
||||
)
|
||||
|
||||
;(function(){
|
||||
"use strict";
|
||||
|
||||
|
||||
// anim.min.js
|
||||
var anim=function(h){h=function(a,e,f,b){var g,d,c=[],j=function(a){
|
||||
if(a=c.shift())a[1]?h.apply(this,a).anim(j):0<a[0]?setTimeout(j,1E3*a[0]):(a[0](),j())};
|
||||
a.charAt&&(a=document.getElementById(a));if(0<a||!a)e={},f=0,j(c=[[a||0]]);
|
||||
q(e,{padding:0,margin:0,border:"Width"},[l,m,n,p]);q(e,{borderRadius:"Radius"},[l+p,l+m,n+m,n+p]);++r;
|
||||
for(g in e)d=e[g],!d.to&&0!==d.to&&(d=e[g]={to:d}),h.defs(d,a,g,b);h.iter(e,1E3*f,j);
|
||||
return{anim:function(){c.push([].slice.call(arguments));return this}}};
|
||||
var l="Top", m="Right",n="Bottom",p="Left",r=1,q=function(a,e,f,b,g,d,c){for(b in a)if(b in e){c=a[b];
|
||||
for(g=0;d=f[g];g++)a[b.replace(e[b],"")+d+(e[b]||"")]={to:0===c.to?c.to:c.to||c,fr:c.fr,e:c.e};
|
||||
delete a[b]}},s=function(w,a){return w["r"+a]||w["webkitR"+a]||w["mozR"+a]||w["msR"+a]||w["oR"+a]}(
|
||||
window,"equestAnimationFrame");h.defs=function(a,e,f,b,g){g=e.style;a.a=f;a.n=e;a.s=f in g?g:e;
|
||||
a.e=a.e||b;a.fr=a.fr||(0===a.fr?0:a.s==e?e[f]:(window.getComputedStyle?getComputedStyle(e, null)
|
||||
:e.currentStyle)[f]);a.u=(/\d(\D+)$/.exec(a.to)||/\d(\D+)$/.exec(a.fr)||[0,0])[1];a.fn=/color/i.test(f)?
|
||||
h.fx.color:h.fx[f]||h.fx._;a.mx="anim_"+f;e[a.mx]=a.mxv=r;e[a.mx]!=a.mxv&&(a.mxv=null)};h.iter=function(a,e,f){
|
||||
var b,g,d,c,h,k=+new Date+e;b=function(){g=k-(new Date).getTime();if(50>g){
|
||||
for(d in a)d=a[d],d.p=1,d.fn(d,d.n,d.to,d.fr,d.a,d.e);f&&f()}else{g/=e;for(d in a){d=a[d];
|
||||
if(d.n[d.mx]!=d.mxv)return;h=d.e;c=g;"lin"==h?c=1-c:"ease"==h?(c=2*(0.5-c),c=1-(c*c*c-3*c+2)/4):
|
||||
"ease-in"==h?(c= 1-c,c*=c*c):c=1-c*c*c;d.p=c;d.fn(d,d.n,d.to,d.fr,d.a,d.e)}s?s(b):setTimeout(b,20)}};
|
||||
b()};h.fx={_:function(a,e,f,b,g){b=parseFloat(b)||0;f=parseFloat(f)||0;a.s[g]=(1<=a.p?f:a.p*(f-b)+b)+a.u},
|
||||
width:function(a,e,f,b,g,d){0<=a._fr||(a._fr=!isNaN(b=parseFloat(b))?b:"width"==g?e.clientWidth:e.clientHeight);
|
||||
h.fx._(a,e,f,a._fr,g,d)},opacity:function(a,e,f,b,g){if(isNaN(b=b||a._fr))b=e.style,b.zoom=1,
|
||||
b=a._fr=(/alpha\(opacity=(\d+)\b/i.exec(b.filter)||{})[1]/100||1;b*=1;f=a.p*(f-b)+b;e=e.style;g in e?e[g]= f:
|
||||
e.filter=1<=f?"":"alpha("+g+"="+Math.round(100*f)+")"},color:function(a,e,f,b,g,d,c,j){
|
||||
a.ok||(f=a.to=h.toRGBA(f),b=a.fr=h.toRGBA(b),0==f[3]&&(f=[].concat(b),f[3]=0),0==b[3]&&
|
||||
(b=[].concat(f),b[3]=0),a.ok=1);j=[0,0,0,a.p*(f[3]-b[3])+1*b[3]];for(c=2;0<=c;c--)j[c]=Math.round(
|
||||
a.p*(f[c]-b[c])+1*b[c]);(1<=j[3]||h.rgbaIE)&&j.pop();try{a.s[g]=(3<j.length?"rgba(":"rgb(")+j.join(",")+")"
|
||||
}catch(k){h.rgbaIE=1}}};h.fx.height=h.fx.width;
|
||||
h.RGBA=/#(.)(.)(.)\b|#(..)(..)(..)\b|(\d+)%,(\d+)%,(\d+)%(?:,([\d\.]+))?|(\d+),(\d+),(\d+)(?:,([\d\.]+))?\b/;
|
||||
h.toRGBA=function(a,e){e=[0,0,0,0];a.replace(/\s/g,"").replace(h.RGBA,function(a,b,g,d,c,h,k,l,m,n,p,q,r,s,t){
|
||||
k=[b+b||c,g+g||h,d+d||k];b=[l,m,n];for(a=0;3>a;a++)k[a]=parseInt(k[a],16),b[a]=Math.round(2.55*b[a]);
|
||||
e=[k[0]||b[0]||q||0,k[1]||b[1]||r||0,k[2]||b[2]||s||0,p||t||1]});return e};return h}();
|
||||
|
||||
|
||||
if (!window.MSStream &&
|
||||
/mac|ipad|iphone|ipod/i.test(navigator.userAgent))
|
||||
{
|
||||
isMac = true
|
||||
document.body.classList.add('mac_or_ios')
|
||||
if (navigator.userAgent.indexOf('Safari') != -1) {
|
||||
document.body.classList.add('safari')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// timeNow() :float
|
||||
var timeNow = (
|
||||
window.performance !== undefined && window.performance.now ? function() {
|
||||
return window.performance.now()
|
||||
} : Date.now ? function() {
|
||||
return Date.now()
|
||||
} : function() {
|
||||
return (new Date()).getTime()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// download-link
|
||||
fetchjson('/inter/info.json', function(err, data) {
|
||||
if (err) { throw err }
|
||||
var ids = Object.keys(data)
|
||||
var regularId = ids[0]
|
||||
ids.forEach(function(id){
|
||||
if (id.indexOf('Inter UI Regular:') == 0) {
|
||||
regularId = id
|
||||
}
|
||||
})
|
||||
if (ids.length == 0) {
|
||||
console.error('failed to find Inter UI Regular in info.json', data)
|
||||
return
|
||||
}
|
||||
var regular = data[regularId]
|
||||
// console.log('info.json:', regular)
|
||||
if (regular.names && regular.names.version) {
|
||||
var v = regular.names.version
|
||||
var p = v.indexOf(';')
|
||||
if (p != -1) {
|
||||
v = v.substr(0, p)
|
||||
}
|
||||
var directDownloadURL =
|
||||
'https://github.com/rsms/inter/releases/download/v' + v +
|
||||
'/Inter-UI-' + v + '.zip'
|
||||
var av = document.querySelectorAll('a.download-link'), i, e
|
||||
for (i = 0; i < av.length; ++i) {
|
||||
e = av[i]
|
||||
e.href = directDownloadURL
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// Google Analytics
|
||||
;(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-105091131-2', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
})();
|
||||
|
|
@ -6,8 +6,8 @@ body {
|
|||
font: 15px/22px 'Inter UI', system-ui, sans-serif;
|
||||
|
||||
font-size: 15px;
|
||||
line-height:1.4;
|
||||
/*letter-spacing: 0.009em;*/
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.002em;
|
||||
|
||||
font-weight: 400;
|
||||
padding-bottom: 30px;
|
||||
|
|
@ -83,11 +83,11 @@ q:after {
|
|||
content: "";
|
||||
}
|
||||
kbd {
|
||||
-moz-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-ms-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-o-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-moz-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-ms-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-o-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
-webkit-font-feature-settings: 'kern' 1, 'case' 1;
|
||||
font-feature-settings: 'kern' 1, 'case' 1;
|
||||
font-feature-settings: 'kern' 1, 'case' 1;
|
||||
border: 1px solid rgba(0,0,0,0.18);
|
||||
border-radius: 3px;
|
||||
padding:0.1em 0.2em;
|
||||
|
|
@ -98,14 +98,20 @@ dem { /* de-emphasize */
|
|||
opacity: 0.7;
|
||||
}
|
||||
num { /* number */
|
||||
-moz-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
/*-moz-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-webkit-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
font-feature-settings: 'calt' 1, 'ss01' 1;*/
|
||||
letter-spacing:0.02em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.013em;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-weight: 500;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
|
@ -176,11 +182,32 @@ h1 > a, h2 > a, h3 > a {
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.row > * {
|
||||
width:100%;
|
||||
max-width: 888px;
|
||||
flex: 1 0 100%;
|
||||
.row > * {
|
||||
width:100%;
|
||||
max-width: 888px;
|
||||
flex: 1 0 100%;
|
||||
}
|
||||
.row .learn-more {
|
||||
margin-top: 2em;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.007em;
|
||||
}
|
||||
.row .learn-more a {
|
||||
color: rgba(0,0,0,0.4);
|
||||
text-decoration-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
.row .learn-more a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.row.full-width {
|
||||
padding: 50px 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.row.full-width > * {
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
.row-divider {
|
||||
margin:0 auto;
|
||||
|
|
@ -228,77 +255,6 @@ h1 > a, h2 > a, h3 > a {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 565px) {
|
||||
.row.menu ul {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.row.menu ul li {
|
||||
margin-right: 15px;
|
||||
}
|
||||
.row.menu ul li:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.row.menu ul li.home {
|
||||
/*color: red;
|
||||
clear: both;*/
|
||||
/*display: block;*/
|
||||
text-align:center;
|
||||
margin:0 0 -12px 0;
|
||||
width: 100%;
|
||||
}
|
||||
.row.menu ul li.home > a {
|
||||
border-bottom: none;
|
||||
padding: 0 1em;
|
||||
margin: 0.5em 0;
|
||||
line-height:34px;
|
||||
border-radius: 90px;
|
||||
|
||||
/*color: white;
|
||||
background-color: rgba(3, 102, 214, 1);*/
|
||||
}
|
||||
.row.menu ul li.home > a:hover {
|
||||
color: white;
|
||||
background-color: #222;
|
||||
}
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 6+) */
|
||||
@media only screen and (max-device-width: 414px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.row {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.row.menu ul {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 5) */
|
||||
@media only screen and (max-device-width: 320px) {
|
||||
.row.menu {
|
||||
font-size:13px;
|
||||
}
|
||||
.row.menu ul {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.row.menu ul li {
|
||||
flex: 1 0 auto;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0,0,0,0.1);
|
||||
margin-left:0;
|
||||
margin-right:0;
|
||||
}
|
||||
.row.menu ul li:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
.row.white {
|
||||
background: white;
|
||||
|
|
@ -346,13 +302,9 @@ a > img {
|
|||
}
|
||||
|
||||
.sample-images {}
|
||||
.sample-images > img, .sample-images > svg {
|
||||
.sample-images img, .sample-images svg {
|
||||
display: block;
|
||||
margin:100px 0;
|
||||
width:100%;
|
||||
}
|
||||
.sample-images > img:first-child, .sample-images > svg:first-child {
|
||||
margin-top:50px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -493,16 +445,16 @@ boxes {
|
|||
}
|
||||
box {
|
||||
overflow: auto;
|
||||
max-width:100%;
|
||||
flex: 1 1 0;
|
||||
min-width: 280px;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: white;
|
||||
padding:2em;
|
||||
padding: 2em;
|
||||
border-radius: 3px;
|
||||
margin-right:1em;
|
||||
margin-bottom:1em;
|
||||
flex: 1 1 10%;
|
||||
/*width:220px;*/
|
||||
}
|
||||
body.safari box {
|
||||
/* Fix for broken flex wrap in safari */
|
||||
|
|
@ -514,3 +466,85 @@ box:first-child {
|
|||
box h3 {
|
||||
margin-bottom:0.8em;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 565px) {
|
||||
.row.menu ul {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.row.menu ul li {
|
||||
margin-right: 15px;
|
||||
}
|
||||
.row.menu ul li:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.row.menu ul li.home {
|
||||
/*color: red;
|
||||
clear: both;*/
|
||||
/*display: block;*/
|
||||
text-align:center;
|
||||
margin:0 0 -12px 0;
|
||||
width: 100%;
|
||||
}
|
||||
.row.menu ul li.home > a {
|
||||
border-bottom: none;
|
||||
padding: 0 1em;
|
||||
margin: 0.5em 0;
|
||||
line-height:34px;
|
||||
border-radius: 90px;
|
||||
|
||||
/*color: white;
|
||||
background-color: rgba(3, 102, 214, 1);*/
|
||||
}
|
||||
.row.menu ul li.home > a:hover {
|
||||
color: white;
|
||||
background-color: #222;
|
||||
}
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 6+) */
|
||||
@media only screen and (max-device-width: 414px) {
|
||||
box { padding: 1em; }
|
||||
box tablex r { font-size: 0.9em; }
|
||||
body {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.row {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.row.menu ul {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 5) */
|
||||
@media only screen and (max-device-width: 320px) {
|
||||
box {
|
||||
font-size: 0.8em;
|
||||
min-width: 240px;
|
||||
}
|
||||
/*.row.menu {
|
||||
font-size:13px;
|
||||
}
|
||||
.row.menu ul {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.row.menu ul li {
|
||||
flex: 1 0 auto;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0,0,0,0.1);
|
||||
margin-left:0;
|
||||
margin-right:0;
|
||||
}
|
||||
.row.menu ul li:last-child {
|
||||
border-right: none;
|
||||
}*/
|
||||
}
|
||||
|
||||
74
docs/res/base.js
Normal file
74
docs/res/base.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
function $$(query, el) {
|
||||
return [].slice.call((el || document).querySelectorAll(query))
|
||||
}
|
||||
|
||||
function $(query, el) {
|
||||
return (el || document).querySelector(query)
|
||||
}
|
||||
|
||||
// fetchjson(url string) :Promise<Object>
|
||||
//
|
||||
var fetchjson = (
|
||||
typeof window.fetch == 'function' ? (
|
||||
function _fetchjson(url, cb) {
|
||||
return window.fetch(url).then(function(r) { return r.json() })
|
||||
}
|
||||
) :
|
||||
function _fetchjson(url, cb) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var r = new XMLHttpRequest()
|
||||
r.addEventListener("load", function(){
|
||||
try {
|
||||
resolve(JSON.parse(r.responseText))
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
r.addEventListener("error", function(ev) {
|
||||
reject(ev.error || ev || new Error('network error'))
|
||||
})
|
||||
r.open("GET", url)
|
||||
r.send()
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// timeNow() :float
|
||||
//
|
||||
var timeNow = (
|
||||
window.performance !== undefined && window.performance.now ? function() {
|
||||
return window.performance.now()
|
||||
} : Date.now ? function() {
|
||||
return Date.now()
|
||||
} : function() {
|
||||
return (new Date()).getTime()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// Mac or not? Maybe even a buggy Safari?
|
||||
var isMac = false
|
||||
if (!window.MSStream &&
|
||||
/mac|ipad|iphone|ipod/i.test(navigator.userAgent))
|
||||
{
|
||||
isMac = true
|
||||
if (navigator.userAgent.indexOf('Safari') != -1 &&
|
||||
navigator.userAgent.indexOf('Chrome') == -1)
|
||||
{
|
||||
document.body.classList.add('safari')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Google Analytics
|
||||
// ;(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
// (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
// m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
// })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
// ga('create', 'UA-105091131-2', 'auto');
|
||||
// ga('send', 'pageview');
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push(['js', new Date()])
|
||||
window.dataLayer.push(['config', 'UA-105091131-2'])
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
// requires index.js
|
||||
|
||||
function passThrough(v) { return v }
|
||||
|
||||
function Binding(name){
|
||||
this.name = name
|
||||
this.value = undefined
|
||||
this.inputs = []
|
||||
this.listeners = []
|
||||
this.formatter = undefined
|
||||
this.parser = undefined
|
||||
this.formatter = passThrough
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -22,7 +25,7 @@ Binding.prototype.addInput = function(el) {
|
|||
if (this.value === undefined) {
|
||||
this.value = el.value
|
||||
} else {
|
||||
input.el.value = this.value
|
||||
input.el.value = this.formatter(this.value)
|
||||
}
|
||||
el.addEventListener('input', _onInput, {passive:true})
|
||||
}
|
||||
|
|
@ -39,8 +42,8 @@ Binding.prototype.addListener = function(listener) {
|
|||
Binding.prototype.setValue = function(nextval, origin) {
|
||||
// console.log('Binding.setValue nextval:', nextval, {origin})
|
||||
var prevval = this.value
|
||||
if (this.formatter) {
|
||||
nextval = this.formatter(nextval, prevval)
|
||||
if (this.parser) {
|
||||
nextval = this.parser(nextval, prevval)
|
||||
}
|
||||
if (this.value === nextval) {
|
||||
return
|
||||
|
|
@ -49,7 +52,7 @@ Binding.prototype.setValue = function(nextval, origin) {
|
|||
this.value = nextval
|
||||
this.inputs.forEach(function(input) {
|
||||
if (input.el !== origin) {
|
||||
input.el.value = nextval
|
||||
input.el.value = binding.formatter(nextval)
|
||||
}
|
||||
})
|
||||
this.listeners.forEach(function(listener) {
|
||||
|
|
@ -106,6 +109,11 @@ Bindings.prototype.setValue = function(name, value) {
|
|||
binding.setValue(value)
|
||||
}
|
||||
|
||||
Bindings.prototype.setFormatter = function(name, formatter) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.formatter = formatter || passThrough
|
||||
}
|
||||
|
||||
|
||||
Bindings.prototype.value = function(name, defaultValue) {
|
||||
var binding = this.bindings[name]
|
||||
|
|
@ -125,11 +133,11 @@ function fmt_int(nextval, prevval) {
|
|||
|
||||
|
||||
// configure is convenience function for setting value, adding a
|
||||
// listener and associating a formatter with a binding.
|
||||
// listener and associating a parser with a binding.
|
||||
// If a listener and a value is provided, the value is set and the listener
|
||||
// is immediately invoked.
|
||||
//
|
||||
Bindings.prototype.configure = function(name, value, formatter, listener) {
|
||||
Bindings.prototype.configure = function(name, value, parser, listener) {
|
||||
var binding = this.getBinding(name)
|
||||
if (listener) {
|
||||
binding.addListener(listener)
|
||||
|
|
@ -137,23 +145,23 @@ Bindings.prototype.configure = function(name, value, formatter, listener) {
|
|||
if (value !== undefined && value !== null) {
|
||||
binding.setValue(value)
|
||||
}
|
||||
if (formatter) {
|
||||
if (typeof formatter == 'string') {
|
||||
switch (formatter) {
|
||||
if (parser) {
|
||||
if (typeof parser == 'string') {
|
||||
switch (parser) {
|
||||
case 'number':
|
||||
case 'float':
|
||||
formatter = fmt_float; break;
|
||||
parser = fmt_float; break;
|
||||
|
||||
case 'int':
|
||||
case 'integer':
|
||||
formatter = fmt_int; break;
|
||||
parser = fmt_int; break;
|
||||
|
||||
default:
|
||||
throw new Error('unknown formatter "' + formatter + '"')
|
||||
throw new Error('unknown parser "' + parser + '"')
|
||||
}
|
||||
} else if (typeof formatter != 'function') {
|
||||
throw new Error('formatter should be a string or function')
|
||||
} else if (typeof parser != 'function') {
|
||||
throw new Error('parser should be a string or function')
|
||||
}
|
||||
binding.formatter = formatter
|
||||
binding.parser = parser
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 700 B After Width: | Height: | Size: 700 B |
239
docs/res/graphplot.js
Normal file
239
docs/res/graphplot.js
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
|
||||
function GraphPlot(canvas) {
|
||||
this.canvas = canvas
|
||||
const g = canvas.getContext('2d')
|
||||
if (g == null) {
|
||||
throw new Error('failed to acquire 2d context')
|
||||
}
|
||||
|
||||
this.width = 0 // dp
|
||||
this.height = 0 // dp
|
||||
this.widthPx = 0 // px
|
||||
this.heightPx = 0 // px
|
||||
this.pixelRatio = 1
|
||||
this.g = g
|
||||
this.dataSegments = []
|
||||
this.axes = {
|
||||
x0: .5, // % from left to x=0
|
||||
y0: .5, // % from top to y=0
|
||||
scalex: 40, // pixels from x=0 to x=1
|
||||
scaley: 40, // pixels from y=0 to y=1
|
||||
negativeX: true,
|
||||
}
|
||||
|
||||
if (!this.autosize()) {
|
||||
this.setSize(256, 256)
|
||||
}
|
||||
}
|
||||
|
||||
GraphPlot.prototype.autosize = function() {
|
||||
try {
|
||||
this.canvas.width = null
|
||||
this.canvas.height = null
|
||||
this.canvas.style.width = null
|
||||
this.canvas.style.height = null
|
||||
var cs = window.getComputedStyle(this.canvas)
|
||||
var width = parseFloat(cs.width)
|
||||
var height = parseFloat(cs.height)
|
||||
this.setSize(width, height)
|
||||
return true
|
||||
} catch (err) {
|
||||
if (typeof console != 'undefined' && console.warn) {
|
||||
console.warn('GraphPlot.autosize failed: ' + err)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// setOrigin sets the origin of axis x and y
|
||||
// The values should be in the range [0-1] and maps to the extremes
|
||||
// of the canvas.
|
||||
//
|
||||
GraphPlot.prototype.setOrigin = function(x, y) {
|
||||
var p = this
|
||||
p.axes.x0 = x
|
||||
p.axes.y0 = y
|
||||
}
|
||||
|
||||
// setScale sets the value scale for x and y axis.
|
||||
// The values should be provided as display points.
|
||||
//
|
||||
GraphPlot.prototype.setScale = function(x, y) {
|
||||
var p = this
|
||||
if (y === undefined) {
|
||||
y = x
|
||||
}
|
||||
p.axes.scalex = x
|
||||
p.axes.scaley = y
|
||||
}
|
||||
|
||||
// setSize sets the size of canvas in display points
|
||||
//
|
||||
GraphPlot.prototype.setSize = function(width, height) {
|
||||
var p = this
|
||||
p.width = width
|
||||
p.height = height
|
||||
const el = p.canvas, g = p.g
|
||||
p.pixelRatio = window.devicePixelRatio || 1
|
||||
if (p.pixelRatio != 1) {
|
||||
el.width = p.widthPx = width * p.pixelRatio
|
||||
el.height = p.heightPx = height * p.pixelRatio
|
||||
g.scale(p.pixelRatio, p.pixelRatio)
|
||||
} else {
|
||||
el.width = p.widthPx = width
|
||||
el.height = p.heightPx = height
|
||||
g.scale(1, 1)
|
||||
}
|
||||
el.style.width = `${width}px`
|
||||
el.style.height = `${height}px`
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.renderAxes = function() {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = Math.round(p.axes.x0 * p.widthPx) / p.pixelRatio
|
||||
, y0 = Math.round(p.axes.y0 * p.heightPx) / p.pixelRatio
|
||||
|
||||
g.beginPath()
|
||||
g.strokeStyle = "rgb(0, 0, 0, 0.2)"
|
||||
if (y0 > 0 && y0 < p.width) {
|
||||
g.moveTo(0, y0); g.lineTo(p.width, y0) // X axis
|
||||
}
|
||||
if (x0 > 0 && x0 < p.height) {
|
||||
g.moveTo(x0, 0); g.lineTo(x0, p.height) // Y axis
|
||||
}
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotf plots an arbitrary function on the graph
|
||||
//
|
||||
GraphPlot.prototype.plotf = function(f, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, w = p.width
|
||||
, h = p.height
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, dx = 4 / p.pixelRatio // smaller means finer curves and more CPU
|
||||
, scalex = p.axes.scalex * w
|
||||
, scaley = p.axes.scaley * h
|
||||
, iMax = Math.round((w - x0) / dx)
|
||||
, iMin = p.axes.negativeX ? Math.round(-x0 / dx) : 0
|
||||
|
||||
g.beginPath()
|
||||
g.lineWidth = 1
|
||||
g.strokeStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
for (var i = iMin; i <= iMax; i++) {
|
||||
x = dx * i
|
||||
y = f(x / scalex) * scaley
|
||||
if (i == iMin) {
|
||||
g.moveTo(x0 + x, y0 - y)
|
||||
} else {
|
||||
g.lineTo(x0 + x, y0 - y)
|
||||
}
|
||||
}
|
||||
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotLines draws straight lines between a collection of points
|
||||
//
|
||||
GraphPlot.prototype.plotLine = function(points, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, scalex = p.axes.scalex * p.width
|
||||
, scaley = p.axes.scaley * p.height
|
||||
, pt
|
||||
|
||||
g.beginPath()
|
||||
g.lineWidth = 1
|
||||
g.strokeStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
var i = 0
|
||||
for (; i < points.length; i++) {
|
||||
pt = points[i]
|
||||
x = pt[0] * scalex
|
||||
y = pt[1] * scaley
|
||||
if (i == 0) {
|
||||
g.moveTo(x0 + x, y0 - y)
|
||||
} else {
|
||||
g.lineTo(x0 + x, y0 - y)
|
||||
}
|
||||
}
|
||||
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotPoints draws points
|
||||
//
|
||||
GraphPlot.prototype.plotPoints = function(points, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, scalex = p.axes.scalex * p.width
|
||||
, scaley = p.axes.scaley * p.height
|
||||
, pt
|
||||
, i = 0
|
||||
|
||||
g.fillStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
for (; i < points.length; i++) {
|
||||
pt = points[i]
|
||||
x = x0 + pt[0] * scalex
|
||||
y = y0 - pt[1] * scaley
|
||||
g.beginPath()
|
||||
g.arc(x, y, 3, 0, Math.PI + (Math.PI * 2) / 2, false)
|
||||
g.fill()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.clear = function() {
|
||||
var p = this
|
||||
p.g.clearRect(0, 0, p.width, p.height)
|
||||
p.renderAxes()
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.renderDemo = function() {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, dpscale = p.pixelRatio
|
||||
, w = p.widthPx
|
||||
, h = p.heightPx
|
||||
|
||||
p.clear()
|
||||
|
||||
p.plotf(
|
||||
function(x) { return Math.sin(x) },
|
||||
'blue'
|
||||
)
|
||||
|
||||
p.plotf(
|
||||
function(x) { return Math.cos(3*x) },
|
||||
'hotpink'
|
||||
)
|
||||
|
||||
// var scale = p.height / 4
|
||||
// g.moveTo(0, scale)
|
||||
// var i, sine, lines = 200, frag = p.width / lines
|
||||
// for (i = 0; i < lines; i++) {
|
||||
// sine = Math.sin(i / scale * 2) * scale
|
||||
// g.lineTo(i * frag, -sine + scale)
|
||||
// }
|
||||
// g.stroke()
|
||||
}
|
||||
243
docs/samples/index.css
Normal file
243
docs/samples/index.css
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
body {
|
||||
padding-bottom: 0;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.row.footer h2 {
|
||||
margin:0;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
livesample {
|
||||
display: block;
|
||||
color: #111;
|
||||
outline: none;
|
||||
padding-left: 20px;
|
||||
border-left: 2px solid transparent;
|
||||
margin-left:-22px;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1.6em;
|
||||
}
|
||||
livesample:hover {
|
||||
/*color: rgb(3, 102, 214);*/
|
||||
border-left-color: rgb(3, 102, 214);
|
||||
}
|
||||
livesample:focus {
|
||||
border-left-color: #eee;
|
||||
}
|
||||
livesample > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
livesample.s1 {
|
||||
padding-left: 16px;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 5em;
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
livesample.s2 {
|
||||
max-width: 400px;
|
||||
font-size: 1em;
|
||||
}
|
||||
livesample.s3 {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
livesample.s3 b, livesample.s3 strong {
|
||||
font-weight:500;
|
||||
color: black;
|
||||
}
|
||||
|
||||
livesample.col3 {
|
||||
-moz-column-width: 20em;
|
||||
-moz-columns: 20em;
|
||||
-webkit-columns: 20em;
|
||||
columns: 20em;
|
||||
|
||||
-moz-column-gap: 2em;
|
||||
-webkit-column-gap: 2em;
|
||||
column-gap: 2em;
|
||||
}
|
||||
livesample.col2 {
|
||||
-moz-column-count: 2;
|
||||
-webkit-column-count: 2;
|
||||
column-count: 2;
|
||||
}
|
||||
|
||||
.font-style-regular { font-weight:400 !important; font-style:normal !important; }
|
||||
.font-style-italic { font-weight:400 !important; font-style:italic !important; }
|
||||
.font-style-medium { font-weight:500 !important; font-style:normal !important; }
|
||||
.font-style-medium-italic { font-weight:500 !important; font-style:italic !important; }
|
||||
.font-style-bold { font-weight:700 !important; font-style:normal !important; }
|
||||
.font-style-bold-italic { font-weight:700 !important; font-style:italic !important; }
|
||||
.font-style-black { font-weight:900 !important; font-style:normal !important; }
|
||||
.font-style-black-italic { font-weight:900 !important; font-style:italic !important; }
|
||||
|
||||
div.live {
|
||||
margin-top:1em;
|
||||
margin-bottom:100px;
|
||||
padding-bottom:20px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
div.live .learn-more {
|
||||
margin-top:40px;
|
||||
user-select: none;
|
||||
}
|
||||
div.controls {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 150px;
|
||||
width: 250px;
|
||||
padding: 10px 0;
|
||||
/*background:#eee;*/
|
||||
opacity:0.3;
|
||||
transition: 90ms opacity cubic-bezier(0.25, 0.47, 0.44, 0.93);
|
||||
/*border:1px solid #bbb;*/
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-right:none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
}
|
||||
div.controls:hover {
|
||||
opacity:1;
|
||||
background:#f5f5f5;
|
||||
border-color: transparent;
|
||||
}
|
||||
div.controls .control {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
min-height: 30px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
div.controls .control > * {
|
||||
flex: 1 1 auto;
|
||||
margin:0;
|
||||
margin-right: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
div.controls .control > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
div.controls .control > select {
|
||||
min-width: 6em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
div.controls .control > input,
|
||||
div.controls .control > select {
|
||||
width: 0;
|
||||
outline: none;
|
||||
}
|
||||
div.controls .control > input[type="number"],
|
||||
div.controls .control > input[type="text"] {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px 0;
|
||||
font-size: inherit;
|
||||
/*border-radius: 2px;*/
|
||||
}
|
||||
div.controls .control > input[type="number"] {
|
||||
max-width: 48px;
|
||||
text-align: right;
|
||||
-moz-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-webkit-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
}
|
||||
div.controls .control > input[type=number]::-webkit-inner-spin-button,
|
||||
div.controls .control > input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
div.controls .control > input[type="range"] {
|
||||
/*max-width: 80%;*/
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
}
|
||||
div.controls .control > img.icon,
|
||||
div.controls .control > label {
|
||||
font-family: georgia, serif;
|
||||
font-style: italic;
|
||||
color: black;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
div.controls canvas {
|
||||
height: 200px;
|
||||
}
|
||||
div.controls .control.info,
|
||||
div.controls canvas {
|
||||
transition: 390ms opacity cubic-bezier(0.25, 0.47, 0.44, 0.93);
|
||||
opacity: 0;
|
||||
}
|
||||
div.controls:hover .control.info,
|
||||
div.controls:hover canvas {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 1200px) {
|
||||
div.controls {
|
||||
width: 210px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 1024px) {
|
||||
div.controls {
|
||||
width: 140px;
|
||||
font-size: 11px;
|
||||
}
|
||||
div.controls canvas {
|
||||
display: none;
|
||||
}
|
||||
div.controls .control.info {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
div.controls .control > input[type="range"] {
|
||||
width: 0;
|
||||
flex: 0 1 0%;
|
||||
display: none;
|
||||
}
|
||||
div.controls .control > input[type="number"] {
|
||||
max-width: 100%;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 740px) {
|
||||
livesample.s1 {
|
||||
font-size:4.5em;
|
||||
}
|
||||
div.controls {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 565px) {
|
||||
livesample.s1 {
|
||||
font-size:4em;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 414px) {
|
||||
livesample.s1 {
|
||||
font-size:3.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.sample-images img, .sample-images svg {
|
||||
margin: 100px 0;
|
||||
}
|
||||
.sample-images > img:first-child, .sample-images > svg:first-child {
|
||||
margin-top:50px;
|
||||
}
|
||||
|
|
@ -1,300 +1,73 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Inter UI font family</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta property="og:title" content="Inter UI font family">
|
||||
<meta property="twitter:title" content="Inter UI font family">
|
||||
<meta property="description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="og:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
||||
<meta property="twitter:card" content="summary">
|
||||
<meta property="twitter:site" content="@rsms">
|
||||
<meta property="twitter:creator" content="@rsms">
|
||||
<meta property="og:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="twitter:image" content="https://rsms.me/inter/res/poster.png">
|
||||
<meta property="fb:app_id" content="38027689216">
|
||||
<meta property="og:url" content="https://rsms.me/inter/">
|
||||
<meta property="og:site_name" content="rsms.me">
|
||||
<meta property="og:type" content="product">
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="icon" type="image/png" href="../favicon.png" />
|
||||
<link href="../inter-ui.css?v=2.5" rel="stylesheet">
|
||||
<link href="../index.css?v=5" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-bottom: 0;
|
||||
background: white;
|
||||
}
|
||||
---
|
||||
layout: default
|
||||
title: Samples
|
||||
---
|
||||
{%
|
||||
|
||||
.row.footer h2 {
|
||||
margin:0;
|
||||
text-align:center;
|
||||
}
|
||||
capture url_root
|
||||
%}{% if site.safe == false %}/{% else %}/inter/{% endif
|
||||
%}{%
|
||||
endcapture %}{%
|
||||
|
||||
/*.row.menu {
|
||||
background: white;
|
||||
}*/
|
||||
for file in site.static_files %}{%
|
||||
assign _path = file.path | remove_first: "/inter" %}{%
|
||||
if _path == "/samples/index.css" %}{%
|
||||
assign index_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/bindings.js" %}{%
|
||||
assign bindings_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/graphplot.js" %}{%
|
||||
assign graphplot_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
endif %}{%
|
||||
endfor
|
||||
|
||||
livesample {
|
||||
display: block;
|
||||
color: #111;
|
||||
outline: none;
|
||||
padding-left: 20px;
|
||||
border-left: 2px solid transparent;
|
||||
margin-left:-22px;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1.6em;
|
||||
}
|
||||
livesample:hover {
|
||||
/*color: rgb(3, 102, 214);*/
|
||||
border-left-color: rgb(3, 102, 214);
|
||||
}
|
||||
livesample:focus {
|
||||
border-left-color: #eee;
|
||||
}
|
||||
livesample > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
livesample.s1 {
|
||||
padding-left: 16px;
|
||||
letter-spacing: -0.005em;
|
||||
font-size: 5em;
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
livesample.s2 {
|
||||
max-width: 400px;
|
||||
font-size: 1em;
|
||||
}
|
||||
livesample.s3 {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
livesample.s3 b, livesample.s3 strong {
|
||||
font-weight:500;
|
||||
color: black;
|
||||
}
|
||||
%}
|
||||
<link rel="stylesheet" href="index.css?v={{ index_css_v }}">
|
||||
<script src="{{url_root}}res/bindings.js?v={{ bindings_js_v }}"></script>
|
||||
<script src="{{url_root}}res/graphplot.js?v={{ graphplot_js_v }}"></script>
|
||||
|
||||
livesample.col3 {
|
||||
-moz-column-width: 20em;
|
||||
-moz-columns: 20em;
|
||||
-webkit-columns: 20em;
|
||||
columns: 20em;
|
||||
<div class="row"><div>
|
||||
<div class="live">
|
||||
|
||||
-moz-column-gap: 2em;
|
||||
-webkit-column-gap: 2em;
|
||||
column-gap: 2em;
|
||||
}
|
||||
livesample.col2 {
|
||||
-moz-column-count: 2;
|
||||
-webkit-column-count: 2;
|
||||
column-count: 2;
|
||||
}
|
||||
|
||||
.font-style-regular { font-weight:400 !important; font-style:normal !important; }
|
||||
.font-style-italic { font-weight:400 !important; font-style:italic !important; }
|
||||
.font-style-medium { font-weight:500 !important; font-style:normal !important; }
|
||||
.font-style-medium-italic { font-weight:500 !important; font-style:italic !important; }
|
||||
.font-style-bold { font-weight:700 !important; font-style:normal !important; }
|
||||
.font-style-bold-italic { font-weight:700 !important; font-style:italic !important; }
|
||||
.font-style-black { font-weight:900 !important; font-style:normal !important; }
|
||||
.font-style-black-italic { font-weight:900 !important; font-style:italic !important; }
|
||||
|
||||
div.live {
|
||||
margin-top:1em;
|
||||
margin-bottom:100px;
|
||||
padding-bottom:100px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
div.controls {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 150px;
|
||||
width: 220px;
|
||||
padding: 10px 16px;
|
||||
/*background:#eee;*/
|
||||
opacity:0.3;
|
||||
border:1px solid #bbb;
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-right:none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
div.controls:hover {
|
||||
opacity:1;
|
||||
background:#f5f5f5;
|
||||
border-color: transparent;
|
||||
}
|
||||
div.controls .control {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
height:30px;
|
||||
}
|
||||
div.controls .control > * {
|
||||
/*max-width: 50%;*/
|
||||
flex: 1 1 auto;
|
||||
margin:0;
|
||||
margin-right: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
div.controls .control > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
div.controls .control > select {
|
||||
min-width: 6em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
div.controls .control > input,
|
||||
div.controls .control > select {
|
||||
width: 0;
|
||||
outline: none;
|
||||
}
|
||||
div.controls .control > input[type="number"],
|
||||
div.controls .control > input[type="text"] {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px 0;
|
||||
font-size: 13px;
|
||||
/*border-radius: 2px;*/
|
||||
}
|
||||
div.controls .control > input[type="number"] {
|
||||
max-width: 60px;
|
||||
text-align: right;
|
||||
-moz-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
-webkit-font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
font-feature-settings: 'calt' 1, 'zero' 1, 'tnum' 1;
|
||||
}
|
||||
div.controls .control > input[type="range"] {
|
||||
/*max-width: 80%;*/
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
}
|
||||
div.controls .control > img.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/*div.controls .control > input.foo {
|
||||
background-color: hotpink;
|
||||
border:none;
|
||||
border-radius: 90px;
|
||||
}*/
|
||||
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 1200px) {
|
||||
div.live div.controls {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 1024px) {
|
||||
div.live div.controls {
|
||||
width: 100px;
|
||||
}
|
||||
div.controls .control > input[type="range"] {
|
||||
width: 0;
|
||||
flex: 0 1 0%;
|
||||
display: none;
|
||||
}
|
||||
div.controls .control > input[type="number"] {
|
||||
max-width: 100%;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 740px) {
|
||||
livesample.s1 {
|
||||
font-size:4.5em;
|
||||
}
|
||||
div.live div.controls {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 565px) {
|
||||
livesample.s1 {
|
||||
font-size:4em;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 414px) {
|
||||
livesample.s1 {
|
||||
font-size:3.4em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="row menu">
|
||||
<ul class="menu">
|
||||
<li class="home"><a href="../">Inter UI</a></li>
|
||||
<li><a class="download-link"
|
||||
href="https://github.com/rsms/inter/releases/latest/"
|
||||
>Download</a></li>
|
||||
<li><a href="/inter/samples/" class="active">Samples</a></li>
|
||||
<li><a href="../lab/">Playground</a></li>
|
||||
<li><a href="https://github.com/rsms/inter/">Source</a></li>
|
||||
</ul>
|
||||
<div class="controls">
|
||||
<div class="control">
|
||||
<img title="Style" class="icon" src="icons/style.svg">
|
||||
<select data-binding="style">
|
||||
<option value="regular" default>Regular</option>
|
||||
<option value="italic">Italic</option>
|
||||
<option value="medium" default>Medium</option>
|
||||
<option value="medium-italic">Medium Italic</option>
|
||||
<option value="bold" default>Bold</option>
|
||||
<option value="bold-italic">Bold Italic</option>
|
||||
<option value="black" default>Black</option>
|
||||
<option value="black-italic">Black Italic</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Size" class="icon" src="icons/font-size.svg">
|
||||
<input type="range" min="8" max="100" step="1" data-binding="font-size">
|
||||
<input type="number" min="4" max="400" step="1" data-binding="font-size">
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Letter spacing in EM" class="icon" src="icons/letter-spacing.svg">
|
||||
<input type="range" min="-0.05" max="0.06" step="0.001" data-binding="letter-spacing">
|
||||
<input type="number" min="-0.15" max="1" step="0.001" data-binding="letter-spacing">
|
||||
</div>
|
||||
<canvas class="graphplot">Canvas not Supported</canvas>
|
||||
<div class="control info">
|
||||
<a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row white"><div>
|
||||
<div class="live">
|
||||
<livesample contenteditable class="s1">
|
||||
Fabulous typography encountering spring
|
||||
</livesample>
|
||||
|
||||
<div class="controls">
|
||||
<div class="control">
|
||||
<img title="Style" class="icon" src="icons/style.svg">
|
||||
<select data-binding="style">
|
||||
<option value="regular" default>Regular</option>
|
||||
<option value="italic">Italic</option>
|
||||
<option value="medium" default>Medium</option>
|
||||
<option value="medium-italic">Medium Italic</option>
|
||||
<option value="bold" default>Bold</option>
|
||||
<option value="bold-italic">Bold Italic</option>
|
||||
<option value="black" default>Black</option>
|
||||
<option value="black-italic">Black Italic</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Size" class="icon" src="icons/font-size.svg">
|
||||
<input type="range" min="8" max="100" step="1" data-binding="font-size">
|
||||
<input type="number" min="4" max="400" step="1" data-binding="font-size">
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Letter spacing in EM" class="icon" src="icons/letter-spacing.svg">
|
||||
<input type="range" min="-0.05" max="0.06" step="0.001" data-binding="letter-spacing">
|
||||
<input type="number" min="-0.15" max="1" step="0.001" data-binding="letter-spacing">
|
||||
</div>
|
||||
<!-- <div class="control">
|
||||
<img class="icon" src="icons/font-size.svg">
|
||||
<input type="text" class="foo" data-binding="foo">
|
||||
<input type="text" class="foo" data-binding="foo">
|
||||
</div> -->
|
||||
</div>
|
||||
<livesample contenteditable class="s2">
|
||||
The user interface (UI), in the industrial design field of human-computer
|
||||
interaction, is the space where interactions between humans and machines occur.
|
||||
</livesample>
|
||||
|
||||
<livesample contenteditable class="s1">
|
||||
Fabulous typography encountering spring
|
||||
</livesample>
|
||||
|
||||
<livesample contenteditable class="s2">
|
||||
The user interface (UI), in the industrial design field of human-computer
|
||||
interaction, is the space where interactions between humans and machines occur.
|
||||
</livesample>
|
||||
|
||||
<livesample contenteditable class="s3 col3">
|
||||
<livesample contenteditable class="s3 col3">
|
||||
<p><b>Fire Island Beach</b> is a barrier of sand, stretching for twenty miles
|
||||
along the south coast of Long Island, and separating the Great South Bay
|
||||
from the Atlantic ocean.
|
||||
|
|
@ -350,89 +123,67 @@ When the tide is on the right moon and the wind has blown a gale from
|
|||
the southeast, the strand is entirely submerged, and people upon the
|
||||
main shore three miles away can see the surf breaking over the Beach
|
||||
hills.
|
||||
</p><p>
|
||||
Such a riot of sea and wind strews the whole extent of beach with
|
||||
whatever has been lost or thrown overboard, or torn out of sunken ships.
|
||||
Many a man has made a good week’s work in a single day by what he has
|
||||
found while walking along the Beach when the surf was down.
|
||||
</p><p>
|
||||
“The Captain” knew all this and had patrolled that Beach scores of
|
||||
times.
|
||||
</p><p>
|
||||
Ten years had passed since the first time which laid the habit of
|
||||
wandering along the surf-shore apparently in search of whatever the sea
|
||||
had cast up. Sometimes a spar, sometimes sheets of copper torn from a
|
||||
wreck and carried by a high surf far along the strand, sometimes a
|
||||
vessel’s gilded name, at other times only scattered drift-wood were the
|
||||
rewards of these lonely walks.
|
||||
</p>
|
||||
</livesample>
|
||||
</div>
|
||||
</livesample>
|
||||
<p class="learn-more">
|
||||
|
||||
<!-- <a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics</a> -->
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p class="sample-images">
|
||||
<img src="img/01.png" srcset="img/01@2x.png 2x" width="888">
|
||||
<img src="img/02.png" srcset="img/02@2x.png 2x" width="888">
|
||||
<!-- <img src="img/02.svg" width="888"> -->
|
||||
<img src="img/03.png" srcset="img/03@2x.png 2x" width="888">
|
||||
<img src="img/04.png" srcset="img/04@2x.png 2x" width="888">
|
||||
<img src="img/05.png" srcset="img/05@2x.png 2x" width="888">
|
||||
<img src="img/dark-phone.jpg" srcset="img/dark-phone@2x.jpg 2x" width="888">
|
||||
<img src="img/06.png" srcset="img/06@2x.png 2x" width="888">
|
||||
<img src="img/07.png" srcset="img/07@2x.png 2x" width="888">
|
||||
<img src="img/08.png" srcset="img/08@2x.png 2x" width="888">
|
||||
<img src="img/09.png" srcset="img/09@2x.png 2x" width="888">
|
||||
<img src="img/10.png" srcset="img/10@2x.png 2x" width="888">
|
||||
<img src="img/11.png" srcset="img/11@2x.png 2x" width="888">
|
||||
<img src="img/12.png" srcset="img/12@2x.png 2x" width="888">
|
||||
<img src="img/13.png" srcset="img/13@2x.png 2x" width="888">
|
||||
<img src="img/14.png" srcset="img/14@2x.png 2x" width="888">
|
||||
<img src="img/15.png" srcset="img/15@2x.png 2x" width="888">
|
||||
</p>
|
||||
<p style="text-align:center">
|
||||
<a href="https://www.figma.com/file/WmU5NWr52bnUcqv5os0V4sWi/" class="plain">Open these samples in Figma</a>
|
||||
</p>
|
||||
</div></div>
|
||||
<p class="sample-images">
|
||||
<img src="img/01.png" srcset="img/01@2x.png 2x" width="888">
|
||||
<img src="img/02.png" srcset="img/02@2x.png 2x" width="888">
|
||||
<!-- <img src="img/02.svg" width="888"> -->
|
||||
<img src="img/03.png" srcset="img/03@2x.png 2x" width="888">
|
||||
<img src="img/04.png" srcset="img/04@2x.png 2x" width="888">
|
||||
<img src="img/05.png" srcset="img/05@2x.png 2x" width="888">
|
||||
<img src="img/dark-phone.jpg" srcset="img/dark-phone@2x.jpg 2x" width="888">
|
||||
<img src="img/06.png" srcset="img/06@2x.png 2x" width="888">
|
||||
<img src="img/07.png" srcset="img/07@2x.png 2x" width="888">
|
||||
<img src="img/08.png" srcset="img/08@2x.png 2x" width="888">
|
||||
<img src="img/09.png" srcset="img/09@2x.png 2x" width="888">
|
||||
<img src="img/10.png" srcset="img/10@2x.png 2x" width="888">
|
||||
<img src="img/11.png" srcset="img/11@2x.png 2x" width="888">
|
||||
<img src="img/12.png" srcset="img/12@2x.png 2x" width="888">
|
||||
<img src="img/13.png" srcset="img/13@2x.png 2x" width="888">
|
||||
<img src="img/14.png" srcset="img/14@2x.png 2x" width="888">
|
||||
<img src="img/15.png" srcset="img/15@2x.png 2x" width="888">
|
||||
</p>
|
||||
<p style="text-align:center">
|
||||
<a
|
||||
href="https://www.figma.com/file/WmU5NWr52bnUcqv5os0V4sWi/"
|
||||
class="plain">Open these samples in Figma</a>
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<script src="../index.js?v=2"></script>
|
||||
<script src="bindings.js"></script>
|
||||
<script type="text/javascript">(function(){
|
||||
<script type="text/javascript">(function(){
|
||||
|
||||
|
||||
|
||||
// InterUIDynamicTracking takes the font size in points or pixels and returns
|
||||
// the compensating tracking in EM.
|
||||
// InterUIDynamicTracking produces tracking in EM for the given font size
|
||||
//
|
||||
function InterUIDynamicTracking(fontSize, weightClass) {
|
||||
// if (!weightClass) { -- currently unused
|
||||
// weightClass = 400
|
||||
// }
|
||||
//
|
||||
// y = -0.01021241 + 0.3720623 * e ^ (-0.2808687 * x)
|
||||
// [6-35] 0.05877 .. -0.0101309 (13==0; stops growing around 30-35)
|
||||
// See https://gist.github.com/rsms/8efdbca5f8145a584ed08a7c3d6e5788
|
||||
//
|
||||
return -0.01021241 + 0.3720623 * Math.pow(Math.E, (-0.2808687 * fontSize))
|
||||
|
||||
// y = 0.025 - (ln(x) * 0.01)
|
||||
// return 0.025 - Math.log(fontSize) * 0.01
|
||||
var a = -0.0149, b = 0.298, c = -0.23;
|
||||
return a + b * Math.pow(Math.E, (c * fontSize))
|
||||
}
|
||||
|
||||
|
||||
function InterUIDynamicLeading(fontSize, weightClass) {
|
||||
var lineHeight = Math.round(fontSize * 1.4)
|
||||
//
|
||||
// TODO
|
||||
//
|
||||
// console.log(
|
||||
// 'lineHeight:', lineHeight,
|
||||
// `(${Math.round(fontSize * 1.45)})`,
|
||||
// )
|
||||
|
||||
return lineHeight
|
||||
// InterUIDynamicLineHeight produces the line height for the given font size
|
||||
//
|
||||
function InterUIDynamicLineHeight(fontSize, weightClass) {
|
||||
var l = 1.4
|
||||
return Math.round(fontSize * l)
|
||||
}
|
||||
|
||||
|
||||
var bindings = new Bindings()
|
||||
var graph = new GraphPlot($('canvas.graphplot'))
|
||||
graph.setOrigin(-0.2, 0.8)
|
||||
graph.setScale(0.049, 5)
|
||||
|
||||
var s2 = $('livesample.s2')
|
||||
|
||||
|
|
@ -443,22 +194,39 @@ function updateWidth() {
|
|||
s2.style.maxWidth = Math.round(w) + 'px'
|
||||
}
|
||||
|
||||
function updateTracking() {
|
||||
var fontSize = bindings.value('font-size', 0)
|
||||
var letterSpacing = InterUIDynamicTracking(fontSize, 400)
|
||||
bindings.setValue('letter-spacing', letterSpacing)
|
||||
}
|
||||
|
||||
function updateGraph() {
|
||||
graph.clear()
|
||||
var fontSize = bindings.value('font-size', 0)
|
||||
var letterSpacing = bindings.value('letter-spacing')
|
||||
graph.plotf(function(x) {
|
||||
return InterUIDynamicTracking(x, 400)
|
||||
})
|
||||
var graphedFontSize = Math.min(24, fontSize) // clamp to [-inf,24]
|
||||
graph.plotPoints([[graphedFontSize, letterSpacing]], '#000')
|
||||
}
|
||||
|
||||
bindings.configure('letter-spacing', 0, 'float', function (letterSpacing) {
|
||||
s2.style.letterSpacing = letterSpacing + 'em'
|
||||
updateWidth()
|
||||
updateGraph()
|
||||
})
|
||||
bindings.setFormatter('letter-spacing', function(v) {
|
||||
return v.toFixed(3)
|
||||
})
|
||||
|
||||
bindings.configure('font-size', 18, 'int', function(fontSize, prevval) {
|
||||
bindings.configure('font-size', 16, 'float', function(fontSize, prevval) {
|
||||
s2.style.fontSize = fontSize + 'px'
|
||||
updateWidth()
|
||||
updateTracking()
|
||||
|
||||
var letterSpacing = InterUIDynamicTracking(fontSize, 400)
|
||||
letterSpacing = parseFloat(letterSpacing.toFixed(3)) // lower precision
|
||||
|
||||
var lineHeight = InterUIDynamicLeading(fontSize, 400)
|
||||
var lineHeight = InterUIDynamicLineHeight(fontSize, 400)
|
||||
s2.style.lineHeight = lineHeight + 'px'
|
||||
|
||||
bindings.setValue('letter-spacing', letterSpacing)
|
||||
})
|
||||
|
||||
bindings.configure('style', null, null, function (style) {
|
||||
|
|
@ -478,8 +246,14 @@ bindings.configure('style', null, null, function (style) {
|
|||
bindings.bindAllInputs('div.live .control input')
|
||||
bindings.bindAllInputs('div.live .control select')
|
||||
|
||||
// resize canvas when window resizes
|
||||
var resizeDebounceTimer = null
|
||||
window.addEventListener('resize', function(){
|
||||
clearTimeout(resizeDebounceTimer)
|
||||
resizeDebounceTimer = setTimeout(function(){
|
||||
graph.autosize()
|
||||
updateGraph()
|
||||
}, 500)
|
||||
}, {passive:true, capture:false})
|
||||
|
||||
|
||||
})();</script>
|
||||
</body>
|
||||
</html>
|
||||
})();</script>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if [ ! -s lab/fonts ]; then
|
||||
ln -s ../../build/dist lab/fonts
|
||||
fi
|
||||
|
||||
if (which caddy >/dev/null); then
|
||||
caddy_args=(\
|
||||
-host localhost \
|
||||
"bind localhost" \
|
||||
"mime .woff2 font/woff2" \
|
||||
"mime .woff application/font-woff" \
|
||||
)
|
||||
caddy "${caddy_args[@]}"
|
||||
elif (which servedir >/dev/null); then
|
||||
servedir
|
||||
else
|
||||
echo "Can not find 'caddy' nor 'servedir' in PATH." >&2
|
||||
echo "Install caddy from brew, apt or https://caddyserver.com/download"
|
||||
echo "or install servedir with 'npm install -g secure-servedir'"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -7,6 +7,7 @@ import os
|
|||
import sys
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from base64 import b64encode
|
||||
|
||||
from fontTools import ttLib
|
||||
|
|
@ -288,6 +289,13 @@ def genFontInfo(fontpath, outputType, withGlyphs=True):
|
|||
if 'subfamilyName' in nameDict:
|
||||
info['name'] += '-' + nameDict['subfamilyName'].replace(' ', '')
|
||||
|
||||
if 'version' in nameDict:
|
||||
version = nameDict['version']
|
||||
v = re.split(r'[\s;]+', version)
|
||||
if v and len(v) > 0:
|
||||
version = v[0]
|
||||
info['version'] = version
|
||||
|
||||
if outputType is not OUTPUT_TYPE_GLYPHLIST:
|
||||
if len(nameDict):
|
||||
info['names'] = nameDict
|
||||
|
|
@ -425,7 +433,7 @@ def main():
|
|||
|
||||
args = argparser.parse_args()
|
||||
|
||||
fonts = {}
|
||||
fonts = []
|
||||
outputType = OUTPUT_TYPE_COMPLETE
|
||||
if args.asGlyphList:
|
||||
outputType = OUTPUT_TYPE_GLYPHLIST
|
||||
|
|
@ -437,7 +445,7 @@ def main():
|
|||
# internal cache that mixes up values for different fonts.
|
||||
reload(sstruct)
|
||||
font = genFontInfo(fontpath, outputType=outputType, withGlyphs=args.withGlyphs)
|
||||
fonts[font['id']] = font
|
||||
fonts.append(font)
|
||||
n += 1
|
||||
|
||||
ostream = sys.stdout
|
||||
|
|
@ -447,6 +455,7 @@ def main():
|
|||
|
||||
if args.prettyJson:
|
||||
json.dump(fonts, ostream, sort_keys=True, indent=2, separators=(',', ': '))
|
||||
sys.stdout.write('\n')
|
||||
else:
|
||||
json.dump(fonts, ostream, separators=(',', ':'))
|
||||
|
||||
|
|
|
|||
Reference in a new issue