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
|
build
|
||||||
/_*
|
/_*
|
||||||
/docs/lab/fonts
|
/docs/lab/fonts
|
||||||
|
/docs/_site
|
||||||
|
|
||||||
src/FontInspector.html
|
src/FontInspector.html
|
||||||
src/svg
|
src/svg
|
||||||
|
|
|
||||||
6
Makefile
6
Makefile
|
|
@ -159,13 +159,13 @@ install_otf: all_otf
|
||||||
install: install_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
|
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
|
misc/gen-glyphorder.py src/Inter-UI-*.ufo > src/glyphorder.txt
|
||||||
|
|
||||||
docs/info.json: misc/fontinfo.py docs/font-files/Inter-UI-*.otf
|
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/info.json
|
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
|
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 \
|
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": {
|
"head": {
|
||||||
"checkSumAdjustment": 3690365233,
|
"checkSumAdjustment": 3690365233,
|
||||||
"created": 3563720514,
|
"created": 3563720514,
|
||||||
|
|
@ -117,6 +117,7 @@
|
||||||
"minMemType42": 0,
|
"minMemType42": 0,
|
||||||
"underlinePosition": -422,
|
"underlinePosition": -422,
|
||||||
"underlineThickness": 170
|
"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
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
pushd res >/dev/null
|
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#">
|
layout: default
|
||||||
<head>
|
title: Glyphs
|
||||||
<meta charset="utf-8">
|
---
|
||||||
<title>Repertoire – Inter UI font family</title>
|
{%
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
capture url_root
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
%}{% if site.safe == false %}/{% else %}/inter/{% endif
|
||||||
|
%}{%
|
||||||
|
endcapture %}{%
|
||||||
|
|
||||||
<meta property="og:title" content="Inter UI font family">
|
for file in site.static_files %}{%
|
||||||
<meta property="twitter:title" content="Inter UI font family">
|
assign _path = file.path | remove_first: "/inter" %}{%
|
||||||
<meta property="description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
if _path == "/glyphs/glyphs.css" %}{%
|
||||||
<meta property="og:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
assign glyphs_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||||
<meta property="twitter:description" content="Inter UI is a new typeface optimized for computer user interfaces">
|
elsif _path == "/glyphs/glyphs.js" %}{%
|
||||||
<meta property="twitter:card" content="summary">
|
assign glyphs_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||||
<meta property="twitter:site" content="@rsms">
|
endif %}{%
|
||||||
<meta property="twitter:creator" content="@rsms">
|
endfor
|
||||||
<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="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 rel="stylesheet" href="glyphs.css?v={{ glyphs_css_v }}">
|
||||||
|
<div id="svgs">
|
||||||
<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">
|
|
||||||
<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-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-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>
|
<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>
|
<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><!--END-SVGS don't remove this comment-->
|
||||||
|
|
||||||
<div class="row intro"><div>
|
<div class="row intro"><div>
|
||||||
<h2 class="back"><a href="../">The Inter UI font family</a></h2>
|
<h1><a href="./">Glyphs</a></h1>
|
||||||
<h1><a href="./">Inter UI glyphs</a></h1>
|
<p>
|
||||||
<p>
|
This shows the complete set of glyphs in Inter UI Regular.
|
||||||
This shows the complete set of glyphs in Inter UI Regular.
|
You can zoom in and out by pressing
|
||||||
You can zoom in and out by pressing
|
<kbd>⌘</kbd><kbd>+</kbd> and
|
||||||
<kbd>⌘</kbd><kbd>+</kbd> and
|
<kbd>⌘</kbd><kbd>−</kbd> on your keyboard.
|
||||||
<kbd>⌘</kbd><kbd>−</kbd> on your keyboard.
|
Click on a glyph to see more details about it.
|
||||||
Click on a glyph to see more details about it.
|
</p>
|
||||||
</p>
|
</div></div>
|
||||||
</div></div>
|
|
||||||
|
|
||||||
<div id="glyphs">
|
<div id="glyphs">
|
||||||
<div id="single-info" style="display:none">
|
<div id="single-info" style="display:none">
|
||||||
<ul>
|
<ul>
|
||||||
<li>Glyph name: <span class="name"></span></li>
|
<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 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>Advance width: <span class="advanceWidth num"></span></li>
|
||||||
<li>Left margin: <span class="marginLeft num"></span></li>
|
<li>Left margin: <span class="marginLeft num"></span></li>
|
||||||
<li>Right margin: <span class="marginRight num"></span></li>
|
<li>Right margin: <span class="marginRight num"></span></li>
|
||||||
<li>Color mark: <span class="colorMark"> </span></li>
|
<li>Color mark: <span class="colorMark"> </span></li>
|
||||||
<li><a class="svgFile">↓ Download SVG file</a></li>
|
<li><a class="svgFile">↓ Download SVG file</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row kerning"><div>
|
<div class="row kerning"><div>
|
||||||
<h2 id="kerning"><a href="#kerning">Kerning</a></h2>
|
<h2 id="kerning"><a href="#kerning">Kerning</a></h2>
|
||||||
<div id="kerning-list"></div>
|
<div id="kerning-list"></div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|
||||||
<script src="glyphs.js"></script>
|
<script src="glyphs.js?v={{ glyphs_js_v }}"></script>
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
||||||
606
docs/index.html
606
docs/index.html
|
|
@ -1,360 +1,326 @@
|
||||||
<!DOCTYPE HTML>
|
---
|
||||||
<html lang="en" prefix="og: http://ogp.me/ns#">
|
layout: default
|
||||||
<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>
|
|
||||||
|
|
||||||
<div class="row menu">
|
<div class="row"><div>
|
||||||
<ul class="menu">
|
<h1>The Inter UI font family</h1>
|
||||||
<li class="home"><a href="../">Inter UI</a></li>
|
<p>
|
||||||
<li><a class="download-link"
|
Inter UI is a typeface specially designed for user interfaces
|
||||||
href="https://github.com/rsms/inter/releases/latest/"
|
with focus on high legibility of small-to-medium sized text on computer screens.
|
||||||
>Download</a></li>
|
</p>
|
||||||
<li><a href="samples/">Samples</a></li>
|
<p>
|
||||||
<li><a href="lab/">Playground</a></li>
|
The family features a tall x-height to aid in readability of mixed-case and
|
||||||
<li><a href="https://github.com/rsms/inter/">Source</a></li>
|
lower-case text. Several OpenType features are provided as well,
|
||||||
</ul>
|
like contextual alternates that adjusts punctuation depending on the shape of
|
||||||
</div>
|
surrounding glyphs, slashed zero for when you need to disambiguate "0" from "o",
|
||||||
|
tabular numbers, etc.
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
<div class="row"><div>
|
<div class="row white" style="padding-bottom:0"><div>
|
||||||
<h1>The Inter UI font family</h1>
|
<p id="samples" class="samples items sample-images">
|
||||||
<p>
|
<a href="samples/" class="plain"><img src="samples/img/01.png" srcset="samples/img/01@2x.png 2x" width="888"></a>
|
||||||
Inter UI is a typeface specially designed for user interfaces
|
</p>
|
||||||
with focus on high legibility of small-to-medium sized text on computer screens.
|
<p style="text-align:center">
|
||||||
</p>
|
<a href="samples/" class="plain">More samples -></a>
|
||||||
<p>
|
<br><br>
|
||||||
The family features a tall x-height to aid in readability of mixed-case and
|
</p>
|
||||||
lower-case text. Several OpenType features are provided as well,
|
</div></div>
|
||||||
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>
|
<div class="row dark"><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>
|
<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> </p>
|
||||||
<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>
|
<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> </p>
|
||||||
<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></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>
|
</div></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>
|
<div class="row"><div>
|
||||||
<h3>Tabular numbers (<q title='OpenType feature ID'>tnum</q>)</h3>
|
<p>
|
||||||
<tablex><t>
|
There are currently four <a id="weights" href="#weights">weights</a>
|
||||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
</p>
|
||||||
<r><in><em>1</em>23456<em>7</em>890</in><to></to><out class="tnum">1234567890</out></r>
|
<img src="res/weights-and-styles.svg" style="opacity:0.76;width:100%;display:block;margin:2em 0 3em 0">
|
||||||
<r><in>1131711<em> </em></in><to></to><out class="tnum">1131711<em> </em></out></r>
|
<h2><a id="features" href="#features">Features</a></h2>
|
||||||
<r><in>0040900<em> </em></in><to></to><out class="tnum">0040900<em> </em></out></r>
|
<boxes>
|
||||||
<r><in>11:31,711<em> </em></in><to></to><out class="tnum">11:31,711<em> </em></out></r>
|
<box>
|
||||||
<r><in>00:40.900<em> </em></in><to></to><out class="tnum">00:40.900<em> </em></out></r>
|
<h3>Contextual alternates (<q title='OpenType feature ID'>calt</q>)</h3>
|
||||||
</t></tablex>
|
<tablex><t>
|
||||||
</box>
|
<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>
|
<box>
|
||||||
<h3>Slashed zero (<q title='OpenType feature ID'>zero</q>)</h3>
|
<h3>Tabular numbers (<q title='OpenType feature ID'>tnum</q>)</h3>
|
||||||
<tablex><t>
|
<tablex><t>
|
||||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
<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>
|
<r><in><em>1</em>23456<em>7</em>890</in><to></to><out class="tnum">1234567890</out></r>
|
||||||
</t></tablex>
|
<r><in>1131711<em> </em></in><to></to><out class="tnum">1131711<em> </em></out></r>
|
||||||
</box>
|
<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>
|
<box>
|
||||||
<h3>Fractions (<q title='OpenType feature ID'>frac</q>)</h3>
|
<h3>Slashed zero (<q title='OpenType feature ID'>zero</q>)</h3>
|
||||||
<tablex><t>
|
<tablex><t>
|
||||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||||
<r>
|
<r><in><em>0</em>123</in><to></to><out class="zero">0123</out></r>
|
||||||
<in><em>1/3</em> <em>22/9</em> <em>3/4/5</em></in>
|
</t></tablex>
|
||||||
<to></to><out class="frac">1/3 22/9 3/4/5</out>
|
</box>
|
||||||
</r>
|
|
||||||
</t></tablex>
|
|
||||||
</box>
|
|
||||||
|
|
||||||
<box>
|
<box>
|
||||||
<h3>Stylistic set 1: Alternate digits (<q title='OpenType feature ID'>ss01</q>)</h3>
|
<h3>Fractions (<q title='OpenType feature ID'>frac</q>)</h3>
|
||||||
<tablex><t>
|
<tablex><t>
|
||||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||||
<r>
|
<r>
|
||||||
<in><em>1</em>23<em>4</em>5<em>6</em>78<em>9</em>0</in>
|
<in><em>1/3</em> <em>22/9</em> <em>3/4/5</em></in>
|
||||||
<to></to><out class="ss01">1234567890</out>
|
<to></to><out class="frac">1/3 22/9 3/4/5</out>
|
||||||
</r>
|
</r>
|
||||||
<r><in><em>1</em></in><to></to><out class="ss01">1</out></r>
|
</t></tablex>
|
||||||
<r><in><em>4</em></in><to></to><out class="ss01">4</out></r>
|
</box>
|
||||||
<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>
|
<box>
|
||||||
<h3>Case alternates (<q title='OpenType feature ID'>case</q>)</h3>
|
<h3>Stylistic set 1: Alternate digits (<q title='OpenType feature ID'>ss01</q>)</h3>
|
||||||
<tablex><t>
|
<tablex><t>
|
||||||
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
<h><in>Disabled</in><to></to><out>Enabled</out></h>
|
||||||
<r>
|
<r>
|
||||||
<in><em>(</em>Hello<em>)</em> <em>[</em>World<em>]</em> <em>{</em>9000<em>}</em></in>
|
<in><em>1</em>23<em>4</em>5<em>6</em>78<em>9</em>0</in>
|
||||||
<to></to><out class="case">(Hello) [World] {9000}</out>
|
<to></to><out class="ss01">1234567890</out>
|
||||||
</r>
|
</r>
|
||||||
<r><in>SCHOOL <em>@</em> RUN</in><to></to><out class="case">SCHOOL @ RUN</out></r>
|
<r><in><em>1</em></in><to></to><out class="ss01">1</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>4</em></in><to></to><out class="ss01">4</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>6</em></in><to></to><out class="ss01">6</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>
|
<r><in><em>9</em></in><to></to><out class="ss01">9</out></r>
|
||||||
</t></tablex>
|
</t></tablex>
|
||||||
</box>
|
</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>
|
</boxes>
|
||||||
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>
|
|
||||||
|
|
||||||
<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>
|
<p> </p>
|
||||||
</div></div>
|
|
||||||
|
|
||||||
<div class="row-divider"></div>
|
<h2 class="banner"><a href="glyphs/">Browse all glyphs -></a></h2>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
<div class="row"><div>
|
<div class="row-divider"></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>
|
|
||||||
|
|
||||||
<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> </p>
|
||||||
<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>
|
<h2><a id="status" href="#status">Current status & usability</a></h2>
|
||||||
Please refer to the <a href="glyphs/">glyph repertoire</a>
|
<p>
|
||||||
for an overview of currently-available glyphs and their quality.
|
Inter UI works great for English-language text, and pretty well for other
|
||||||
</p>
|
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>
|
<p> </p>
|
||||||
<ul class="faq">
|
|
||||||
|
|
||||||
<li class="q" id="faq-using-features">
|
<h2><a id="faq" href="#faq">FAQ</a></h2>
|
||||||
How do I enable and disable font features?
|
<ul class="faq">
|
||||||
</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">
|
<li class="q" id="faq-using-features">
|
||||||
What is the difference between "unhinted" and "hinted" font files?
|
How do I enable and disable font features?
|
||||||
</li>
|
</li>
|
||||||
<li class="a">
|
<li class="a">
|
||||||
The font files in the "hinted" folders have additional data in them
|
In web browsers you'll want to use
|
||||||
for assisting
|
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings"><q>font-feature-settings</q></a>.
|
||||||
<a href="https://en.wikipedia.org/wiki/ClearType">ClearType</a>,
|
In Figma you can access features via the
|
||||||
the text rasterizer used by Microsoft Windows (and some Linux distributions.)
|
<a href="https://help.figma.com/text/opentype-features">Advanced Typography panel.</a>
|
||||||
You want to use the "hinted" fonts only if you are targeting Windows users
|
In Illustrator, Photoshop and friends, you can access features via the
|
||||||
<em>and</em> prefer the different look of these "hinted" fonts.
|
<a href="https://helpx.adobe.com/illustrator/using/special-characters.html#opentype_panel_overview">Characters and OpenType panels.</a>
|
||||||
Additionally, hinting data makes the font files larger, so if you are
|
Sketch doesn't provide a UI for configuring font features, but there's
|
||||||
using Inter UI on websites, the extra size of these files is another
|
<a href="https://sketchtalk.io/discussion/comment/1478/#Comment_1478">a workaround using macOS's native font UI.</a>
|
||||||
consideration to make.
|
</li>
|
||||||
<a href="https://www.typotheque.com/articles/hinting">
|
|
||||||
This article explains hinting at a greater length.</a>
|
<li class="q" id="faq-unhinted-vs-hinted">
|
||||||
</li>
|
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">
|
<li class="q" id="faq-cdn">
|
||||||
How reliable are the fonts served from rsms.me/inter? Is it on a CDN?
|
How reliable are the fonts served from rsms.me/inter? Is it on a CDN?
|
||||||
</li>
|
</li>
|
||||||
<li class="a">
|
<li class="a">
|
||||||
rsms.me/inter is backed by GitHub's server network and distributed
|
rsms.me/inter is backed by GitHub's server network and distributed
|
||||||
globally on the CloudFlare CDN, making usage of
|
globally on the CloudFlare CDN, making usage of
|
||||||
<q>https://rsms.me/inter/inter-ui.css</q> and associated font
|
<q>https://rsms.me/inter/inter-ui.css</q> and associated font
|
||||||
files very reliable and fast throughout the world.
|
files very reliable and fast throughout the world.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="q" id="faq-contribute">
|
<li class="q" id="faq-contribute">
|
||||||
Can I help with improving Inter UI?
|
Can I help with improving Inter UI?
|
||||||
</li>
|
</li>
|
||||||
<li class="a">
|
<li class="a">
|
||||||
Yes you can! Inter UI is an open-source project, meaning the source
|
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
|
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.
|
<a href="https://github.com/rsms/inter">are freely available</a> to improve upon.
|
||||||
Font making requires a fair bit of technical work and
|
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 what you'd like to do, some things might be more fun
|
||||||
depending on your technical skills.
|
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
|
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
|
you can have the biggest impact, how things are setup and how to get
|
||||||
started.
|
started.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="q" id="faq-start-date">
|
<li class="q" id="faq-start-date">
|
||||||
This website claims work started in 2016, but the git repository's log says it started later?
|
This website claims work started in 2016, but the git repository's log says it started later?
|
||||||
</li>
|
</li>
|
||||||
<li class="a">
|
<li class="a">
|
||||||
Inter UI was developed in an a private, internal git repository
|
Inter UI was developed in an a private, internal git repository
|
||||||
starting in November 2016, prior to being published on August 22, 2017.
|
starting in November 2016, prior to being published on August 22, 2017.
|
||||||
Between November 2016 and August 2017, there were
|
Between November 2016 and August 2017, there were
|
||||||
<num>2 990 150</num> line edits made across 247 versions.
|
<num>2 990 150</num> line edits made across 247 versions.
|
||||||
The reason the public GitHub repository does not reflect this is the
|
The reason the public GitHub repository does not reflect this is the
|
||||||
fact that the project was initially only internal at the company where
|
fact that the project was initially only internal at the company where
|
||||||
the author works and had some sensitive information "checked in",
|
the author works and had some sensitive information "checked in",
|
||||||
like AWS server details and internal author identity in
|
like AWS server details and internal author identity in
|
||||||
all commit messages. Maybe one day we can write an elaborate git
|
all commit messages. Maybe one day we can write an elaborate git
|
||||||
filter-branch program and convert the filter the old repository to make
|
filter-branch program and convert the filter the old repository to make
|
||||||
it public, but what would be the point of that? :—)
|
it public, but what would be the point of that? :—)
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="q" id="faq-contact">
|
<li class="q" id="faq-contact">
|
||||||
I've made a cool thing that uses Inter UI, can I share it with you?
|
I've made a cool thing that uses Inter UI, can I share it with you?
|
||||||
<dem>or</dem>
|
<dem>or</dem>
|
||||||
</li>
|
</li>
|
||||||
<li class="q">
|
<li class="q">
|
||||||
I have a different question
|
I have a different question
|
||||||
</li>
|
</li>
|
||||||
<li class="a">
|
<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>
|
Reach out on <a href="https://twitter.com/rsms">Twitter (@rsms)</a> or over <a href="mailto:rasmus@notion.se">email</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|
||||||
|
|
||||||
<div class="row"><div>
|
<div class="row"><div>
|
||||||
— <a href="https://twitter.com/rsms" class="plain">@rsms</a>
|
— <a href="https://twitter.com/rsms" class="plain">@rsms</a>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|
||||||
<script src="index.js?v=2"></script>
|
<script>(function(){
|
||||||
<script>
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
// FAQ anchors
|
// FAQ anchors
|
||||||
var av = document.querySelectorAll('ul.faq > li.q'), a, i, e, id, tn
|
var av = document.querySelectorAll('ul.faq > li.q'), a, i, e, id, tn
|
||||||
for (i = 0; i < av.length; ++i) {
|
for (i = 0; i < av.length; ++i) {
|
||||||
e = av[i]
|
e = av[i]
|
||||||
tn = document.createTextNode('Q ')
|
tn = document.createTextNode('Q ')
|
||||||
e.insertBefore(tn, e.firstChild)
|
e.insertBefore(tn, e.firstChild)
|
||||||
id = e.id
|
id = e.id
|
||||||
if (id) {
|
if (id) {
|
||||||
a = document.createElement('a')
|
a = document.createElement('a')
|
||||||
// a.id = id
|
// a.id = id
|
||||||
a.href = '#' + id
|
a.href = '#' + id
|
||||||
a.className = 'plain'
|
a.className = 'plain'
|
||||||
a.innerHTML = e.innerHTML
|
a.innerHTML = e.innerHTML
|
||||||
e.innerText = ''
|
e.innerText = ''
|
||||||
e.appendChild(a)
|
e.appendChild(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av = document.querySelectorAll('ul.faq > li.a')
|
av = document.querySelectorAll('ul.faq > li.a')
|
||||||
for (i = 0; i < av.length; ++i) {
|
for (i = 0; i < av.length; ++i) {
|
||||||
e = av[i]
|
e = av[i]
|
||||||
tn = document.createTextNode('A ')
|
tn = document.createTextNode('A ')
|
||||||
e.insertBefore(tn, e.firstChild)
|
e.insertBefore(tn, e.firstChild)
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();</script>
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
||||||
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: 15px/22px 'Inter UI', system-ui, sans-serif;
|
||||||
|
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height:1.4;
|
line-height: 1.5;
|
||||||
/*letter-spacing: 0.009em;*/
|
letter-spacing: -0.002em;
|
||||||
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
|
|
@ -83,11 +83,11 @@ q:after {
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
kbd {
|
kbd {
|
||||||
-moz-font-feature-settings: 'kern' 1, 'case' 1;
|
-moz-font-feature-settings: 'kern' 1, 'case' 1;
|
||||||
-ms-font-feature-settings: 'kern' 1, 'case' 1;
|
-ms-font-feature-settings: 'kern' 1, 'case' 1;
|
||||||
-o-font-feature-settings: 'kern' 1, 'case' 1;
|
-o-font-feature-settings: 'kern' 1, 'case' 1;
|
||||||
-webkit-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: 1px solid rgba(0,0,0,0.18);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding:0.1em 0.2em;
|
padding:0.1em 0.2em;
|
||||||
|
|
@ -98,14 +98,20 @@ dem { /* de-emphasize */
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
num { /* number */
|
num { /* number */
|
||||||
-moz-font-feature-settings: 'calt' 1, 'ss01' 1;
|
/*-moz-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||||
-ms-font-feature-settings: 'calt' 1, 'ss01' 1;
|
-ms-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||||
-o-font-feature-settings: 'calt' 1, 'ss01' 1;
|
-o-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||||
-webkit-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;
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.013em;
|
||||||
|
}
|
||||||
|
|
||||||
h1, h2, h3 {
|
h1, h2, h3 {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|
@ -176,11 +182,32 @@ h1 > a, h2 > a, h3 > a {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.row > * {
|
.row > * {
|
||||||
width:100%;
|
width:100%;
|
||||||
max-width: 888px;
|
max-width: 888px;
|
||||||
flex: 1 0 100%;
|
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 {
|
.row-divider {
|
||||||
margin:0 auto;
|
margin:0 auto;
|
||||||
|
|
@ -228,77 +255,6 @@ h1 > a, h2 > a, h3 > a {
|
||||||
opacity: 1;
|
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 {
|
.row.white {
|
||||||
background: white;
|
background: white;
|
||||||
|
|
@ -346,13 +302,9 @@ a > img {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sample-images {}
|
.sample-images {}
|
||||||
.sample-images > img, .sample-images > svg {
|
.sample-images img, .sample-images svg {
|
||||||
display: block;
|
display: block;
|
||||||
margin:100px 0;
|
width: 100%;
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
.sample-images > img:first-child, .sample-images > svg:first-child {
|
|
||||||
margin-top:50px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -493,16 +445,16 @@ boxes {
|
||||||
}
|
}
|
||||||
box {
|
box {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-width:100%;
|
flex: 1 1 0;
|
||||||
|
min-width: 280px;
|
||||||
|
max-width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: white;
|
background: white;
|
||||||
padding:2em;
|
padding: 2em;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
margin-right:1em;
|
margin-right:1em;
|
||||||
margin-bottom:1em;
|
margin-bottom:1em;
|
||||||
flex: 1 1 10%;
|
|
||||||
/*width:220px;*/
|
|
||||||
}
|
}
|
||||||
body.safari box {
|
body.safari box {
|
||||||
/* Fix for broken flex wrap in safari */
|
/* Fix for broken flex wrap in safari */
|
||||||
|
|
@ -514,3 +466,85 @@ box:first-child {
|
||||||
box h3 {
|
box h3 {
|
||||||
margin-bottom:0.8em;
|
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
|
// requires index.js
|
||||||
|
|
||||||
|
function passThrough(v) { return v }
|
||||||
|
|
||||||
function Binding(name){
|
function Binding(name){
|
||||||
this.name = name
|
this.name = name
|
||||||
this.value = undefined
|
this.value = undefined
|
||||||
this.inputs = []
|
this.inputs = []
|
||||||
this.listeners = []
|
this.listeners = []
|
||||||
this.formatter = undefined
|
this.parser = undefined
|
||||||
|
this.formatter = passThrough
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,7 +25,7 @@ Binding.prototype.addInput = function(el) {
|
||||||
if (this.value === undefined) {
|
if (this.value === undefined) {
|
||||||
this.value = el.value
|
this.value = el.value
|
||||||
} else {
|
} else {
|
||||||
input.el.value = this.value
|
input.el.value = this.formatter(this.value)
|
||||||
}
|
}
|
||||||
el.addEventListener('input', _onInput, {passive:true})
|
el.addEventListener('input', _onInput, {passive:true})
|
||||||
}
|
}
|
||||||
|
|
@ -39,8 +42,8 @@ Binding.prototype.addListener = function(listener) {
|
||||||
Binding.prototype.setValue = function(nextval, origin) {
|
Binding.prototype.setValue = function(nextval, origin) {
|
||||||
// console.log('Binding.setValue nextval:', nextval, {origin})
|
// console.log('Binding.setValue nextval:', nextval, {origin})
|
||||||
var prevval = this.value
|
var prevval = this.value
|
||||||
if (this.formatter) {
|
if (this.parser) {
|
||||||
nextval = this.formatter(nextval, prevval)
|
nextval = this.parser(nextval, prevval)
|
||||||
}
|
}
|
||||||
if (this.value === nextval) {
|
if (this.value === nextval) {
|
||||||
return
|
return
|
||||||
|
|
@ -49,7 +52,7 @@ Binding.prototype.setValue = function(nextval, origin) {
|
||||||
this.value = nextval
|
this.value = nextval
|
||||||
this.inputs.forEach(function(input) {
|
this.inputs.forEach(function(input) {
|
||||||
if (input.el !== origin) {
|
if (input.el !== origin) {
|
||||||
input.el.value = nextval
|
input.el.value = binding.formatter(nextval)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.listeners.forEach(function(listener) {
|
this.listeners.forEach(function(listener) {
|
||||||
|
|
@ -106,6 +109,11 @@ Bindings.prototype.setValue = function(name, value) {
|
||||||
binding.setValue(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) {
|
Bindings.prototype.value = function(name, defaultValue) {
|
||||||
var binding = this.bindings[name]
|
var binding = this.bindings[name]
|
||||||
|
|
@ -125,11 +133,11 @@ function fmt_int(nextval, prevval) {
|
||||||
|
|
||||||
|
|
||||||
// configure is convenience function for setting value, adding a
|
// 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
|
// If a listener and a value is provided, the value is set and the listener
|
||||||
// is immediately invoked.
|
// is immediately invoked.
|
||||||
//
|
//
|
||||||
Bindings.prototype.configure = function(name, value, formatter, listener) {
|
Bindings.prototype.configure = function(name, value, parser, listener) {
|
||||||
var binding = this.getBinding(name)
|
var binding = this.getBinding(name)
|
||||||
if (listener) {
|
if (listener) {
|
||||||
binding.addListener(listener)
|
binding.addListener(listener)
|
||||||
|
|
@ -137,23 +145,23 @@ Bindings.prototype.configure = function(name, value, formatter, listener) {
|
||||||
if (value !== undefined && value !== null) {
|
if (value !== undefined && value !== null) {
|
||||||
binding.setValue(value)
|
binding.setValue(value)
|
||||||
}
|
}
|
||||||
if (formatter) {
|
if (parser) {
|
||||||
if (typeof formatter == 'string') {
|
if (typeof parser == 'string') {
|
||||||
switch (formatter) {
|
switch (parser) {
|
||||||
case 'number':
|
case 'number':
|
||||||
case 'float':
|
case 'float':
|
||||||
formatter = fmt_float; break;
|
parser = fmt_float; break;
|
||||||
|
|
||||||
case 'int':
|
case 'int':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
formatter = fmt_int; break;
|
parser = fmt_int; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error('unknown formatter "' + formatter + '"')
|
throw new Error('unknown parser "' + parser + '"')
|
||||||
}
|
}
|
||||||
} else if (typeof formatter != 'function') {
|
} else if (typeof parser != 'function') {
|
||||||
throw new Error('formatter should be a string or 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#">
|
layout: default
|
||||||
<head>
|
title: Samples
|
||||||
<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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row.footer h2 {
|
capture url_root
|
||||||
margin:0;
|
%}{% if site.safe == false %}/{% else %}/inter/{% endif
|
||||||
text-align:center;
|
%}{%
|
||||||
}
|
endcapture %}{%
|
||||||
|
|
||||||
/*.row.menu {
|
for file in site.static_files %}{%
|
||||||
background: white;
|
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;
|
<link rel="stylesheet" href="index.css?v={{ index_css_v }}">
|
||||||
color: #111;
|
<script src="{{url_root}}res/bindings.js?v={{ bindings_js_v }}"></script>
|
||||||
outline: none;
|
<script src="{{url_root}}res/graphplot.js?v={{ graphplot_js_v }}"></script>
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
livesample.col3 {
|
<div class="row"><div>
|
||||||
-moz-column-width: 20em;
|
<div class="live">
|
||||||
-moz-columns: 20em;
|
|
||||||
-webkit-columns: 20em;
|
|
||||||
columns: 20em;
|
|
||||||
|
|
||||||
-moz-column-gap: 2em;
|
<div class="controls">
|
||||||
-webkit-column-gap: 2em;
|
<div class="control">
|
||||||
column-gap: 2em;
|
<img title="Style" class="icon" src="icons/style.svg">
|
||||||
}
|
<select data-binding="style">
|
||||||
livesample.col2 {
|
<option value="regular" default>Regular</option>
|
||||||
-moz-column-count: 2;
|
<option value="italic">Italic</option>
|
||||||
-webkit-column-count: 2;
|
<option value="medium" default>Medium</option>
|
||||||
column-count: 2;
|
<option value="medium-italic">Medium Italic</option>
|
||||||
}
|
<option value="bold" default>Bold</option>
|
||||||
|
<option value="bold-italic">Bold Italic</option>
|
||||||
.font-style-regular { font-weight:400 !important; font-style:normal !important; }
|
<option value="black" default>Black</option>
|
||||||
.font-style-italic { font-weight:400 !important; font-style:italic !important; }
|
<option value="black-italic">Black Italic</option>
|
||||||
.font-style-medium { font-weight:500 !important; font-style:normal !important; }
|
</select>
|
||||||
.font-style-medium-italic { font-weight:500 !important; font-style:italic !important; }
|
</div>
|
||||||
.font-style-bold { font-weight:700 !important; font-style:normal !important; }
|
<div class="control">
|
||||||
.font-style-bold-italic { font-weight:700 !important; font-style:italic !important; }
|
<img title="Size" class="icon" src="icons/font-size.svg">
|
||||||
.font-style-black { font-weight:900 !important; font-style:normal !important; }
|
<input type="range" min="8" max="100" step="1" data-binding="font-size">
|
||||||
.font-style-black-italic { font-weight:900 !important; font-style:italic !important; }
|
<input type="number" min="4" max="400" step="1" data-binding="font-size">
|
||||||
|
</div>
|
||||||
div.live {
|
<div class="control">
|
||||||
margin-top:1em;
|
<img title="Letter spacing in EM" class="icon" src="icons/letter-spacing.svg">
|
||||||
margin-bottom:100px;
|
<input type="range" min="-0.05" max="0.06" step="0.001" data-binding="letter-spacing">
|
||||||
padding-bottom:100px;
|
<input type="number" min="-0.15" max="1" step="0.001" data-binding="letter-spacing">
|
||||||
border-bottom: 1px solid #ddd;
|
</div>
|
||||||
}
|
<canvas class="graphplot">Canvas not Supported</canvas>
|
||||||
div.controls {
|
<div class="control info">
|
||||||
position: absolute;
|
<a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics</a>
|
||||||
right: 0;
|
</div>
|
||||||
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>
|
</div>
|
||||||
|
|
||||||
<div class="row white"><div>
|
<livesample contenteditable class="s1">
|
||||||
<div class="live">
|
Fabulous typography encountering spring
|
||||||
|
</livesample>
|
||||||
|
|
||||||
<div class="controls">
|
<livesample contenteditable class="s2">
|
||||||
<div class="control">
|
The user interface (UI), in the industrial design field of human-computer
|
||||||
<img title="Style" class="icon" src="icons/style.svg">
|
interaction, is the space where interactions between humans and machines occur.
|
||||||
<select data-binding="style">
|
</livesample>
|
||||||
<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="s1">
|
<livesample contenteditable class="s3 col3">
|
||||||
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">
|
|
||||||
<p><b>Fire Island Beach</b> is a barrier of sand, stretching for twenty miles
|
<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
|
along the south coast of Long Island, and separating the Great South Bay
|
||||||
from the Atlantic ocean.
|
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
|
the southeast, the strand is entirely submerged, and people upon the
|
||||||
main shore three miles away can see the surf breaking over the Beach
|
main shore three miles away can see the surf breaking over the Beach
|
||||||
hills.
|
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>
|
</p>
|
||||||
</livesample>
|
</livesample>
|
||||||
</div>
|
<p class="learn-more">
|
||||||
|
|
||||||
|
<!-- <a href="{{url_root}}dynmetrics/">Learn about Dynamic Metrics</a> -->
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="sample-images">
|
<p class="sample-images">
|
||||||
<img src="img/01.png" srcset="img/01@2x.png 2x" width="888">
|
<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.png" srcset="img/02@2x.png 2x" width="888">
|
||||||
<!-- <img src="img/02.svg" 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/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/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/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/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/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/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/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/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/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/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/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/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/14.png" srcset="img/14@2x.png 2x" width="888">
|
||||||
<img src="img/15.png" srcset="img/15@2x.png 2x" width="888">
|
<img src="img/15.png" srcset="img/15@2x.png 2x" width="888">
|
||||||
</p>
|
</p>
|
||||||
<p style="text-align:center">
|
<p style="text-align:center">
|
||||||
<a href="https://www.figma.com/file/WmU5NWr52bnUcqv5os0V4sWi/" class="plain">Open these samples in Figma</a>
|
<a
|
||||||
</p>
|
href="https://www.figma.com/file/WmU5NWr52bnUcqv5os0V4sWi/"
|
||||||
</div></div>
|
class="plain">Open these samples in Figma</a>
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
<script src="../index.js?v=2"></script>
|
<script type="text/javascript">(function(){
|
||||||
<script src="bindings.js"></script>
|
|
||||||
<script type="text/javascript">(function(){
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// InterUIDynamicTracking takes the font size in points or pixels and returns
|
// InterUIDynamicTracking produces tracking in EM for the given font size
|
||||||
// the compensating tracking in EM.
|
|
||||||
//
|
//
|
||||||
function InterUIDynamicTracking(fontSize, weightClass) {
|
function InterUIDynamicTracking(fontSize, weightClass) {
|
||||||
// if (!weightClass) { -- currently unused
|
// if (!weightClass) { -- currently unused
|
||||||
// weightClass = 400
|
// weightClass = 400
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// y = -0.01021241 + 0.3720623 * e ^ (-0.2808687 * x)
|
var a = -0.0149, b = 0.298, c = -0.23;
|
||||||
// [6-35] 0.05877 .. -0.0101309 (13==0; stops growing around 30-35)
|
return a + b * Math.pow(Math.E, (c * fontSize))
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InterUIDynamicLineHeight produces the line height for the given font size
|
||||||
function InterUIDynamicLeading(fontSize, weightClass) {
|
//
|
||||||
var lineHeight = Math.round(fontSize * 1.4)
|
function InterUIDynamicLineHeight(fontSize, weightClass) {
|
||||||
//
|
var l = 1.4
|
||||||
// TODO
|
return Math.round(fontSize * l)
|
||||||
//
|
|
||||||
// console.log(
|
|
||||||
// 'lineHeight:', lineHeight,
|
|
||||||
// `(${Math.round(fontSize * 1.45)})`,
|
|
||||||
// )
|
|
||||||
|
|
||||||
return lineHeight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var bindings = new Bindings()
|
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')
|
var s2 = $('livesample.s2')
|
||||||
|
|
||||||
|
|
@ -443,22 +194,39 @@ function updateWidth() {
|
||||||
s2.style.maxWidth = Math.round(w) + 'px'
|
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) {
|
bindings.configure('letter-spacing', 0, 'float', function (letterSpacing) {
|
||||||
s2.style.letterSpacing = letterSpacing + 'em'
|
s2.style.letterSpacing = letterSpacing + 'em'
|
||||||
updateWidth()
|
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'
|
s2.style.fontSize = fontSize + 'px'
|
||||||
updateWidth()
|
updateWidth()
|
||||||
|
updateTracking()
|
||||||
|
|
||||||
var letterSpacing = InterUIDynamicTracking(fontSize, 400)
|
var lineHeight = InterUIDynamicLineHeight(fontSize, 400)
|
||||||
letterSpacing = parseFloat(letterSpacing.toFixed(3)) // lower precision
|
|
||||||
|
|
||||||
var lineHeight = InterUIDynamicLeading(fontSize, 400)
|
|
||||||
s2.style.lineHeight = lineHeight + 'px'
|
s2.style.lineHeight = lineHeight + 'px'
|
||||||
|
|
||||||
bindings.setValue('letter-spacing', letterSpacing)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
bindings.configure('style', null, null, function (style) {
|
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 input')
|
||||||
bindings.bindAllInputs('div.live .control select')
|
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>
|
||||||
})();</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
||||||
|
|
@ -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 sys
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
|
||||||
from fontTools import ttLib
|
from fontTools import ttLib
|
||||||
|
|
@ -288,6 +289,13 @@ def genFontInfo(fontpath, outputType, withGlyphs=True):
|
||||||
if 'subfamilyName' in nameDict:
|
if 'subfamilyName' in nameDict:
|
||||||
info['name'] += '-' + nameDict['subfamilyName'].replace(' ', '')
|
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 outputType is not OUTPUT_TYPE_GLYPHLIST:
|
||||||
if len(nameDict):
|
if len(nameDict):
|
||||||
info['names'] = nameDict
|
info['names'] = nameDict
|
||||||
|
|
@ -425,7 +433,7 @@ def main():
|
||||||
|
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
fonts = {}
|
fonts = []
|
||||||
outputType = OUTPUT_TYPE_COMPLETE
|
outputType = OUTPUT_TYPE_COMPLETE
|
||||||
if args.asGlyphList:
|
if args.asGlyphList:
|
||||||
outputType = OUTPUT_TYPE_GLYPHLIST
|
outputType = OUTPUT_TYPE_GLYPHLIST
|
||||||
|
|
@ -437,7 +445,7 @@ def main():
|
||||||
# internal cache that mixes up values for different fonts.
|
# internal cache that mixes up values for different fonts.
|
||||||
reload(sstruct)
|
reload(sstruct)
|
||||||
font = genFontInfo(fontpath, outputType=outputType, withGlyphs=args.withGlyphs)
|
font = genFontInfo(fontpath, outputType=outputType, withGlyphs=args.withGlyphs)
|
||||||
fonts[font['id']] = font
|
fonts.append(font)
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
ostream = sys.stdout
|
ostream = sys.stdout
|
||||||
|
|
@ -447,6 +455,7 @@ def main():
|
||||||
|
|
||||||
if args.prettyJson:
|
if args.prettyJson:
|
||||||
json.dump(fonts, ostream, sort_keys=True, indent=2, separators=(',', ': '))
|
json.dump(fonts, ostream, sort_keys=True, indent=2, separators=(',', ': '))
|
||||||
|
sys.stdout.write('\n')
|
||||||
else:
|
else:
|
||||||
json.dump(fonts, ostream, separators=(',', ':'))
|
json.dump(fonts, ostream, separators=(',', ':'))
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue