diff options
-rwxr-xr-x | docs/_scripts/serve.sh | 8 | ||||
-rw-r--r-- | docs/inter-ui.css | 46 | ||||
-rw-r--r-- | docs/lab/index.html | 173 | ||||
-rw-r--r-- | docs/lab/lab.css | 56 | ||||
-rw-r--r-- | docs/lab/var.html | 208 |
5 files changed, 452 insertions, 39 deletions
diff --git a/docs/_scripts/serve.sh b/docs/_scripts/serve.sh index ed795542a..203156643 100755 --- a/docs/_scripts/serve.sh +++ b/docs/_scripts/serve.sh @@ -3,7 +3,7 @@ set -e cd "$(dirname "$0")/.." if [ ! -d lab/fonts ]; then - ln -fs ../../build/unhinted lab/fonts + ln -fs ../../build/fonts lab/fonts fi # jekyll is a little dumb and resolves the lab/fonts symlink and copies @@ -11,15 +11,15 @@ fi # Let's work around that. # # Step 1/2: remove any previous symlink, or jekyll crashes -rm -rf _site/lab/fonts +rm -f _site/lab/fonts # # Step 2/2: create symlink again after some delay. Ugh. sh <<_EOF_ & N=3 while [ \$N -gt 0 ]; do sleep 1 - rm -rf _site/lab/fonts - ln -fs ../../../build/unhinted _site/lab/fonts + rm -f _site/lab/fonts + ln -fs ../../../build/fonts _site/lab/fonts let N=N-1 done _EOF_ diff --git a/docs/inter-ui.css b/docs/inter-ui.css index ccd5a0aff..542b6fd5d 100644 --- a/docs/inter-ui.css +++ b/docs/inter-ui.css @@ -2,14 +2,16 @@ font-family: 'Inter UI'; font-style: normal; font-weight: 400; - src: url("font-files/Inter-UI-Regular.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-Regular.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-Regular.woff?v=2.5") format("woff"); } @font-face { font-family: 'Inter UI'; font-style: italic; font-weight: 400; - src: url("font-files/Inter-UI-Italic.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-Italic.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-Italic.woff?v=2.5") format("woff"); } @@ -17,14 +19,16 @@ font-family: 'Inter UI'; font-style: normal; font-weight: 500; - src: url("font-files/Inter-UI-Medium.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-Medium.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-Medium.woff?v=2.5") format("woff"); } @font-face { font-family: 'Inter UI'; font-style: italic; font-weight: 500; - src: url("font-files/Inter-UI-MediumItalic.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-MediumItalic.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-MediumItalic.woff?v=2.5") format("woff"); } @@ -32,14 +36,16 @@ font-family: 'Inter UI'; font-style: normal; font-weight: 700; - src: url("font-files/Inter-UI-Bold.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-Bold.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-Bold.woff?v=2.5") format("woff"); } @font-face { font-family: 'Inter UI'; font-style: italic; font-weight: 700; - src: url("font-files/Inter-UI-BoldItalic.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-BoldItalic.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-BoldItalic.woff?v=2.5") format("woff"); } @@ -47,13 +53,37 @@ font-family: 'Inter UI'; font-style: normal; font-weight: 900; - src: url("font-files/Inter-UI-Black.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-Black.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-Black.woff?v=2.5") format("woff"); } @font-face { font-family: 'Inter UI'; font-style: italic; font-weight: 900; - src: url("font-files/Inter-UI-BlackItalic.woff2?v=2.5") format("woff2"), + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url("font-files/Inter-UI-BlackItalic.woff2?v=2.5") format("woff2"), url("font-files/Inter-UI-BlackItalic.woff?v=2.5") format("woff"); } + +/* +Single variable font. +Note that you may want to do something like this to make sure you're serving +constant fonts to older browsers: + +html { + font-family: 'Inter UI', sans-serif; +} +@supports (font-variation-settings: normal) { + html { + font-family: 'Inter UI var', sans-serif; + } +} + +*/ +@font-face { + font-family: 'Inter UI var'; + font-weight: 400 900; /* safe weight range */ + src: url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2-variations"), + url('font-files/Inter-UI.var.woff2?v=2.6') format("woff2"); +} diff --git a/docs/lab/index.html b/docs/lab/index.html index 8c1295516..9deb630d3 100644 --- a/docs/lab/index.html +++ b/docs/lab/index.html @@ -753,78 +753,95 @@ for (const ch of uniqueChars) { font-family: 'Inter-UI-VERSION'; font-style: normal; font-weight: 400; - src: url("fonts/Inter-UI-Regular.woff2") format("woff2"), - url("fonts/Inter-UI-Regular.woff") format("woff"); + src: url("fonts/const/Inter-UI-Regular.woff2") format("woff2"), + url("fonts/const/Inter-UI-Regular.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: italic; font-weight: 400; - src: url("fonts/Inter-UI-Italic.woff2") format("woff2"), - url("fonts/Inter-UI-Italic.woff") format("woff"); + src: url("fonts/const/Inter-UI-Italic.woff2") format("woff2"), + url("fonts/const/Inter-UI-Italic.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: normal; font-weight: 500; - src: url("fonts/Inter-UI-Medium.woff2") format("woff2"), - url("fonts/Inter-UI-Medium.woff") format("woff"); + src: url("fonts/const/Inter-UI-Medium.woff2") format("woff2"), + url("fonts/const/Inter-UI-Medium.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: italic; font-weight: 500; - src: url("fonts/Inter-UI-MediumItalic.woff2") format("woff2"), - url("fonts/Inter-UI-MediumItalic.woff") format("woff"); + src: url("fonts/const/Inter-UI-MediumItalic.woff2") format("woff2"), + url("fonts/const/Inter-UI-MediumItalic.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: normal; font-weight: 700; - src: url("fonts/Inter-UI-Bold.woff2") format("woff2"), - url("fonts/Inter-UI-Bold.woff") format("woff"); + src: url("fonts/const/Inter-UI-Bold.woff2") format("woff2"), + url("fonts/const/Inter-UI-Bold.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: italic; font-weight: 700; - src: url("fonts/Inter-UI-BoldItalic.woff2") format("woff2"), - url("fonts/Inter-UI-BoldItalic.woff") format("woff"); + src: url("fonts/const/Inter-UI-BoldItalic.woff2") format("woff2"), + url("fonts/const/Inter-UI-BoldItalic.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: normal; font-weight: 900; - src: url("fonts/Inter-UI-Black.woff2") format("woff2"), - url("fonts/Inter-UI-Black.woff") format("woff"); + src: url("fonts/const/Inter-UI-Black.woff2") format("woff2"), + url("fonts/const/Inter-UI-Black.woff") format("woff"); } @font-face { font-family: 'Inter-UI-VERSION'; font-style: italic; font-weight: 900; - src: url("fonts/Inter-UI-BlackItalic.woff2") format("woff2"), - url("fonts/Inter-UI-BlackItalic.woff") format("woff"); + src: url("fonts/const/Inter-UI-BlackItalic.woff2") format("woff2"), + url("fonts/const/Inter-UI-BlackItalic.woff") format("woff"); } -.inter-ui, .inter-ui input, .inter-ui select { +.inter-ui, +.inter-ui input, +.inter-ui select { font-family: 'Inter-UI-VERSION', 'Inter UI', serif !important; } +@font-face { + font-family: 'Inter-UI-var-VERSION'; + font-weight: 400 900; + src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations"); +} + +body.varfont .inter-ui, +body.varfont .inter-ui input, +body.varfont .inter-ui select { + font-family: 'Inter-UI-var-VERSION', 'Inter UI var', serif !important; +} + </style> <link href="lab.css" rel="stylesheet"> <script type="text/javascript"> const fontVersion = Math.round(Date.now()).toString(36) let fontFamilyName = 'Inter-UI-v' + fontVersion +let fontFamilyNameVar = 'Inter-UI-var-v' + fontVersion const fontCSSTemplate = document.querySelector('#font-css') const fontCSS = fontCSSTemplate.cloneNode(true) fontCSS.innerHTML = fontCSS.innerHTML + .replace(/Inter-UI-var-VERSION/g, fontFamilyNameVar) .replace(/Inter-UI-VERSION/g, fontFamilyName) .replace(/(\.woff2?)/g, '$1?r='+fontVersion) fontFamilyName += ", 'Inter UI'" +fontFamilyNameVar += ", 'Inter UI var'" fontCSS.setAttribute('id', '') fontCSS.setAttribute('type', 'text/css') document.head.appendChild(fontCSS) @@ -833,19 +850,47 @@ document.head.appendChild(fontCSS) </head> <body> <div class="options inter-ui"> - <select name="sample"></select> - <label> - <input type="number" value="13" step="1" min="4" max="1024" name="size"> - <select name="weight" style="max-width:120px"> + <label class="style"> + <select name="weight" style="max-width:100px"> <!--option value="200">Thin (200)</option> <option value="300">Light (300)</option--> <option value="400" selected>Regular (400)</option> <option value="500">Medium (500)</option> <option value="700">Bold (700)</option> + <option value="800">Extra Bold (800)</option> <option value="900">Black (900)</option> </select> <label style="display:inline-block; margin-left:4px"><input type="checkbox" name="italic"> <em>Italic</em></label> + <label> + <input type="checkbox" class="featopt" name="varfont" + title="Enable variable font (experimental!)"> + <span>Variable</span> + </label> + </label> + + <div class="checkbox-group varfontControl"> + <span>Variable axes:</span> + <label class="label-and-value"> + <span>Weight:</span> + <input type="range" value="400" min="400" max="900" name="varWeight"> + <input type="number" value="400" step="1" min="400" max="900" name="varWeightNum"> + </label> + <label class="label-and-value"> + <span>Italic:</span> + <input type="range" value="0" min="0" max="100" name="varItalic"> + <input type="number" value="0" step="1" min="0" max="100" name="varItalicNum"> + </label> + </div> + + <label class="label-and-value"> + <span>Size:</span> + <input type="number" value="13" step="1" min="4" max="1024" name="size"> + </label> + + <label class="label-and-value"> + <span>Sample text:</span> + <select name="sample"></select> </label> <div class="checkbox-group repertoireControl"> @@ -1336,6 +1381,11 @@ function main() { // setCSSProp('line-height', Math.ceil(v * 1.5) + 'px') }) + let usingVarFont = false + var varWeightRange, varItalicRange + var varWeightSettingValueImpl = false + var varItalicSettingValueImpl = false + let currentBodyWeightClass = null vars.bind('weight', (e, v) => { setCSSProp('font-weight', v) @@ -1345,8 +1395,87 @@ function main() { document.body.classList.add(currentBodyWeightClass = 'font-weight-'+v) }) - vars.bind('italic', (e, on) => { + var italicVar = vars.bind('italic', (e, on) => { document.body.classList[on ? 'add' : 'remove']('italic') + if (usingVarFont && !varItalicSettingValueImpl) { + if (varItalicRange) { + varItalicRange.setValue(on ? 100 : 0) + } + updateVarFont() + } + }) + + let varState = { + weight: 400, + italic: 0, + } + + function updateVarFont() { + if (usingVarFont) { + varItalicSettingValueImpl = true + if (varState.italic <= 0.1) { + varState.italic = 0 + italicVar.setValue(false) + } else { + italicVar.setValue(true) + } + varItalicSettingValueImpl = false + setCSSProp( + "font-variation-settings", + `"wght" ${varState.weight}, "ital" ${varState.italic}` + ) + } else { + setCSSProp("font-variation-settings", null) + } + } + + vars.bind('varfont', (e, on) => { + usingVarFont = on + document.body.classList[on ? 'add' : 'remove']('varfont') + document.body.style.fontFamily = on ? fontFamilyNameVar : fontFamilyName; + updateVarFont() + }) + + let varWeightNum = vars.bind('varWeightNum', (e, v) => { + if (varWeightRange && !varWeightSettingValueImpl) { + varWeightRange.setValue(v) + } + }) + + let varItalicNum = vars.bind('varItalicNum', (e, v) => { + if (varItalicRange && !varItalicSettingValueImpl) { + varItalicRange.setValue(v) + } + }) + + varWeightRange = vars.bind('varWeight', (e, v) => { + varState.weight = v + varWeightSettingValueImpl = true + varWeightNum.setValue(v) + varWeightSettingValueImpl = false + updateVarFont() + }, (e, prevValue, ev) => { + if (prevValue === undefined) { + return 400 + } + return e.valueAsNumber !== undefined ? e.valueAsNumber : e.value + }) + + varItalicRange = vars.bind('varItalic', (e, v) => { + varState.italic = v + varItalicSettingValueImpl = true + varItalicNum.setValue(v) + varItalicSettingValueImpl = false + updateVarFont() + }, (e, prevValue, ev) => { + if (prevValue === undefined) { + return 0 + } + return e.valueAsNumber !== undefined ? e.valueAsNumber : e.value + }) + + vars.bind('varItalic', (e, v) => { + console.log('varItalic', v) }) diff --git a/docs/lab/lab.css b/docs/lab/lab.css index a439ee415..b744490c7 100644 --- a/docs/lab/lab.css +++ b/docs/lab/lab.css @@ -12,9 +12,6 @@ body { .systemFont { font-family: system-ui,-apple-system,"SF Pro Text","SF UI Text",BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;, serif; } -.italic { - font-style: italic; -} .de-emphasize { color:#555; } @@ -44,7 +41,7 @@ h2 { top:0; right:0; bottom:0; background:#f4f4f4; padding: 24px; - user-select:none; + user-select:none; -moz-user-select: none; font-family: sans-serif !important; overflow: auto; letter-spacing:0.01em; @@ -73,7 +70,7 @@ h2 { width:90px; } .options .label-and-value input { - width:50px; + width: 50px; } .options .label-and-value select { min-width:50px; @@ -89,9 +86,49 @@ h2 { .options label.rasterizePhrase input { width:100%; } + .options label.style { + display: flex; + align-items: center; + justify-content: space-between; + } + .options input[type="checkbox"] + * { + user-select: none; -moz-user-select: none; + } + .options .varfontControl { + display: none; + } + body.varfont .options .varfontControl { + display: block; + } + .options .varfontControl .label-and-value { + display: flex; + } + .options .varfontControl .label-and-value > span { + padding-left: 10px; + width: 80px; + flex: 0 0 auto; + } + .options .varfontControl input[type="range"] { + flex: 1 1 auto; + } + .options .varfontControl input[type="number"] { + flex: 0 1 auto; + width: 35px; + border: none; + padding: 0; + margin-left: 4px; + } + body.varfont .options select[name="weight"] { + pointer-events: none; + opacity: 0.4; + } input[type="number"] { width:50px; + background: none; + border: 1px solid rgba(0,0,0,0.2); + padding: 4px; + border-radius: 2px; } label { @@ -119,6 +156,15 @@ samples { padding: 24px 0; width:100%; } +body.italic samples { + font-style: italic; +} +body.varfont.italic samples { + /* [BUG] (Safari 11.1) font-style:italic and ital axis is not + mutually exclusive, meaning we have to set either or. */ + font-style: normal; + font-variation-settings: 'ital' 100; +} sample { margin: 0; /*white-space: pre;*/ diff --git a/docs/lab/var.html b/docs/lab/var.html new file mode 100644 index 000000000..947b8d6c5 --- /dev/null +++ b/docs/lab/var.html @@ -0,0 +1,208 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> +<meta charset="utf-8"> +<link href="../inter-ui.css" rel="stylesheet"> +<style type="text/css"> + +@font-face { + font-family: 'Inter UI var'; + font-weight: 400 900; + src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations"), + url('../font-files/Inter-UI.var.woff2') format("woff2-variations"); +} + +html { + font-family: 'Inter UI', sans-serif; + font-size: 14px; + letter-spacing: 0.001em; +} +body { + margin: 0; + padding: 0; +} + +.sample { + padding: 40px 40px 40px 35px; + font-size: 96px; + letter-spacing: -0.03em; + /*font-variation-settings: 'wght' 400, 'ital' 0;*/ +} + +@supports (font-variation-settings: normal) { + html { + font-family: 'Inter UI var', sans-serif; + } +} + +label { + user-select: none; +} + +.ctrl { + display: flex; + /*justify-content:center;*/ + align-items:center; + background: #e5e5e5; + color: #333; + padding:20px 20px 20px 40px; +} + .ctrl input { + margin:0 8px; + } + .ctrl label { + display: flex; + /*justify-content:center;*/ + align-items:center; + margin-right:20px; + } + +</style> +</head> +<body> +<div class="ctrl"> + <label> + Weight: + <input type="range" value="400" min="400" max="900" name="weight"> + </label> + <label> + Italic: + <input type="range" value="0" min="0" max="100" name="italic"> + </label> + <label> + <input type="checkbox" name="animate"> + Animate + </label> +</div> +<div class="sample" contenteditable> +Inter UI 2.6 coming soon <br> +Refined glyphs & kerning <br> +Variable weight axis <br> +Major overhaul 123ABC! <br> +</div> +<script type="text/javascript"> + +var state = { + weight: 400, + italic: 0, +} + +var samples = document.querySelectorAll('div.sample') +var weightInput = document.querySelector('[name="weight"]') +var italicInput = document.querySelector('[name="italic"]') + +weightInput.value = String(state.weight) +italicInput.value = String(state.italic) + +function updateFontVariationSettings() { + for (let i = 0; i < samples.length; i++) { + let sample = samples[i] + // sample.style.fontVariationSettings = + // `'wght' ${state.weight}, 'ital' ${state.italic}` + sample.style.fontVariationSettings = + `'wght' ${state.weight}, 'ital' ${state.italic}` + } +} + +function setWeight(weight) { + state.weight = weight + updateFontVariationSettings() +} + +function setItalic(italic) { + state.italic = italic + updateFontVariationSettings() +} + +// monotime() :float milliseconds +// +var monotime = ( + window.performance !== undefined && window.performance.now ? function() { + return window.performance.now() + } : Date.now ? function() { + return Date.now() + } : function() { + return (new Date()).getTime() + } +) + + +var isAnimating = false +function startAnimation() { + if (isAnimating) { + return + } + weightInput.disabled = true + isAnimating = true + let v = 0 + let wmin = parseFloat(weightInput.min) + , wmax = parseFloat(weightInput.max) + , imin = parseFloat(italicInput.min) + , imax = parseFloat(italicInput.max) + , wspeed = 200 // lower is faster; time divisor + , ispeed = 800 + , clamp = 0.001 + , startTime = monotime() + function update() { + let r = 0, v = 0 + + r = (1 + Math.sin((monotime() - startTime) / wspeed)) * 0.5 + v = (wmin * (1 - clamp)) + (((wmax * (1 + clamp)) - (wmin * (1 - clamp))) * r) + v = Math.max(wmin, Math.min(wmax, v)) + setWeight(v) + weightInput.value = v + + r = (1 + Math.sin((monotime() - startTime) / ispeed)) * 0.5 + v = (imin * (1 - clamp)) + (((imax * (1 + clamp)) - (imin * (1 - clamp))) * r) + v = Math.max(imin, Math.min(imax, v)) + setItalic(v) + italicInput.value = v + + if (isAnimating) { + requestAnimationFrame(update) + } + } + update() +} + +function stopAnimation() { + isAnimating = false + weightInput.disabled = false + weightInput.value = String(state.weight) +} + +// UI control: weight slider +weightInput.addEventListener('input', + weightInput.valueAsNumber !== undefined ? ev => { + setWeight(weightInput.valueAsNumber) + } : ev => { + setWeight(parseFloat(weightInput.value)) + } +) + +// UI control: italic slider +italicInput.addEventListener('input', + italicInput.valueAsNumber !== undefined ? ev => { + setItalic(italicInput.valueAsNumber) + } : ev => { + setItalic(parseFloat(italicInput.value)) + } +) + +// UI control: animate +var animateInput = document.querySelector('[name="animate"]') +if (!window.requestAnimationFrame) { + animateInput.disabled = true +} else { + animateInput.addEventListener('change', ev => { + if (animateInput.checked) { + startAnimation() + } else { + stopAnimation() + } + }) +} + +</script> + </body> +</html>
\ No newline at end of file |