web: VF: slant axis instead of italic axis

This commit is contained in:
Rasmus Andersson 2018-09-30 12:34:27 -07:00
parent 3fba02c38a
commit 6f6f6683ed
5 changed files with 119 additions and 98 deletions

View file

@ -101,7 +101,9 @@
} }
/* /*
Single variable font. ------------------------------------------------------------------------------
Alternative to the above: Single variable font.
Note that you may want to do something like this to make sure you're serving Note that you may want to do something like this to make sure you're serving
constant fonts to older browsers: constant fonts to older browsers:
@ -117,7 +119,8 @@ html {
*/ */
@font-face { @font-face {
font-family: 'Inter UI var'; font-family: 'Inter UI var';
font-weight: 400 900; /* safe weight range */ font-weight: 400 900;
font-style: oblique 0deg 10deg;
src: url("font-files/Inter-UI.var.woff2?v=3.0") format("woff2-variations"), src: url("font-files/Inter-UI.var.woff2?v=3.0") format("woff2-variations"),
url("font-files/Inter-UI.var.woff2?v=3.0") format("woff2"); url("font-files/Inter-UI.var.woff2?v=3.0") format("woff2");
} }

View file

@ -1037,6 +1037,7 @@ for (const ch of uniqueChars) {
@font-face { @font-face {
font-family: 'Inter-UI-var-VERSION'; font-family: 'Inter-UI-var-VERSION';
font-weight: 400 900; font-weight: 400 900;
font-style: oblique 0deg 10deg;
src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations"); src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations");
} }
@ -1134,9 +1135,11 @@ for (const ch of uniqueChars) {
} }
@font-face { @font-face {
/* Note: Not hinted */
font-family: 'Inter-UI-var-hinted-VERSION'; font-family: 'Inter-UI-var-hinted-VERSION';
font-weight: 400 900; font-weight: 400 900;
src: url('fonts/var-hinted/Inter-UI.var.woff2') format("woff2-variations"); font-style: oblique 0deg 10deg;
src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations");
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
@ -1222,9 +1225,9 @@ document.head.appendChild(fontCSS)
<input type="number" value="400" step="1" min="400" max="900" name="varWeightNum"> <input type="number" value="400" step="1" min="400" max="900" name="varWeightNum">
</label> </label>
<label class="label-and-value"> <label class="label-and-value">
<span>Italic:</span> <span>Slant:</span>
<input type="range" value="0" min="0" max="100" name="varItalic"> <input type="range" value="0" step="0.01" min="0" max="10" name="varSlant">
<input type="number" value="0" step="1" min="0" max="100" name="varItalicNum"> <input type="number" value="0" step="1" min="0" max="10" name="varSlantNum">
</label> </label>
</div> </div>
@ -1781,9 +1784,9 @@ function main() {
}) })
let usingVarFont = false let usingVarFont = false
var varWeightRange, varItalicRange var varWeightRange, varSlantRange
var varWeightSettingValueImpl = false var varWeightSettingValueImpl = false
var varItalicSettingValueImpl = false var varSlantSettingValueImpl = false
let currentBodyWeightClass = null let currentBodyWeightClass = null
vars.bind('weight', (e, v) => { vars.bind('weight', (e, v) => {
@ -1796,32 +1799,32 @@ function main() {
var italicVar = vars.bind('italic', (e, on) => { var italicVar = vars.bind('italic', (e, on) => {
document.body.classList[on ? 'add' : 'remove']('italic') document.body.classList[on ? 'add' : 'remove']('italic')
if (usingVarFont && !varItalicSettingValueImpl) { if (usingVarFont && !varSlantSettingValueImpl) {
if (varItalicRange) { if (varSlantRange) {
varItalicRange.setValue(on ? 100 : 0) varSlantRange.setValue(on ? 100 : 0)
} }
updateVarFont() updateVarFont()
} }
}) })
let varState = { let varState = {
weight: 400, weight: 400, // 400-900
italic: 0, slant: 0, // 0-10
} }
function updateVarFont() { function updateVarFont() {
if (usingVarFont) { if (usingVarFont) {
varItalicSettingValueImpl = true varSlantSettingValueImpl = true
if (varState.italic <= 0.1) { if (varState.slant <= 0.1) {
varState.italic = 0 varState.slant = 0
italicVar.setValue(false) italicVar.setValue(false)
} else { } else {
italicVar.setValue(true) italicVar.setValue(true)
} }
varItalicSettingValueImpl = false varSlantSettingValueImpl = false
setCSSProp( setCSSProp(
"font-variation-settings", "font-variation-settings",
`"wght" ${varState.weight}, "ital" ${varState.italic}` `"wght" ${varState.weight}, "slnt" ${varState.slant}`
) )
} else { } else {
setCSSProp("font-variation-settings", null) setCSSProp("font-variation-settings", null)
@ -1851,9 +1854,9 @@ function main() {
} }
}) })
let varItalicNum = vars.bind('varItalicNum', (e, v) => { let varSlantNum = vars.bind('varSlantNum', (e, v) => {
if (varItalicRange && !varItalicSettingValueImpl) { if (varSlantRange && !varSlantSettingValueImpl) {
varItalicRange.setValue(v) varSlantRange.setValue(v)
} }
}) })
@ -1870,11 +1873,11 @@ function main() {
return e.valueAsNumber !== undefined ? e.valueAsNumber : e.value return e.valueAsNumber !== undefined ? e.valueAsNumber : e.value
}) })
varItalicRange = vars.bind('varItalic', (e, v) => { varSlantRange = vars.bind('varSlant', (e, v) => {
varState.italic = v varState.slant = v
varItalicSettingValueImpl = true varSlantSettingValueImpl = true
varItalicNum.setValue(v) varSlantNum.setValue(v)
varItalicSettingValueImpl = false varSlantSettingValueImpl = false
updateVarFont() updateVarFont()
}, (e, prevValue, ev) => { }, (e, prevValue, ev) => {
if (prevValue === undefined) { if (prevValue === undefined) {

View file

@ -154,16 +154,10 @@ samples, boxes {
samples { samples {
display: flex; display: flex;
padding: 24px 0; padding: 24px 0;
width:100%; width: 100%;
} }
body.italic samples { body.italic samples {
font-style: italic; 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 { sample {
margin: 0; margin: 0;

View file

@ -8,6 +8,7 @@
@font-face { @font-face {
font-family: 'Inter UI var'; font-family: 'Inter UI var';
font-weight: 400 900; font-weight: 400 900;
font-style: oblique 0deg 10deg;
src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations"), src: url('fonts/var/Inter-UI.var.woff2') format("woff2-variations"),
url('../font-files/Inter-UI.var.woff2') format("woff2-variations"); url('../font-files/Inter-UI.var.woff2') format("woff2-variations");
} }
@ -24,9 +25,9 @@ body {
.sample { .sample {
padding: 40px 40px 40px 35px; padding: 40px 40px 40px 35px;
font-size: 96px; font-size: var(--size);
letter-spacing: -0.03em; letter-spacing: -0.03em;
/*font-variation-settings: 'wght' 400, 'ital' 0;*/ font-variation-settings: 'wght' var(--weight), 'slnt' var(--slant);
} }
@supports (font-variation-settings: normal) { @supports (font-variation-settings: normal) {
@ -61,58 +62,62 @@ label {
</head> </head>
<body> <body>
<div class="ctrl"> <div class="ctrl">
<label> <label>Weight: <input type="range" value="400" min="400" max="900" name="weight"></label>
Weight: <label>Slant: <input type="range" value="0" min="0" max="10" step="0.01" name="slant"></label>
<input type="range" value="400" min="400" max="900" name="weight"> <label>Size: <input type="range" value="96" min="6" max="400" name="size"></label>
</label>
<label>
Italic:
<input type="range" value="0" min="0" max="100" name="italic">
</label>
<label> <label>
<input type="checkbox" name="animate"> <input type="checkbox" name="animate">
Animate Animate
</label> </label>
</div> </div>
<div class="sample" contenteditable> <div class="sample" contenteditable>
Inter UI 2.6 coming soon <br> Inter UI 3.0 is variable and flexible<br>
Refined glyphs & kerning <br> Variable weight axis<br>
Variable weight axis <br> Variable slant/oblique axis<br>
Major overhaul 123ABC! <br> ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
abcdefghijklmnopqrstuvwxyz<br>
1234567890?!()[]{}&*^%$#@~&lt;&gt;<br>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var state = {
weight: 400,
italic: 0,
}
var samples = document.querySelectorAll('div.sample') var samples = document.querySelectorAll('div.sample')
var weightInput = document.querySelector('[name="weight"]') var weightInput = document.querySelector('[name="weight"]')
var italicInput = document.querySelector('[name="italic"]') var slantInput = document.querySelector('[name="slant"]')
var sizeInput = document.querySelector('[name="size"]')
weightInput.value = String(state.weight)
italicInput.value = String(state.italic)
function updateFontVariationSettings() { var ui = {
for (let i = 0; i < samples.length; i++) { weight: parseFloat(weightInput.value),
let sample = samples[i] slant: parseFloat(slantInput.value),
// sample.style.fontVariationSettings = size: parseFloat(sizeInput.value),
// `'wght' ${state.weight}, 'ital' ${state.italic}`
sample.style.fontVariationSettings = setState(props) {
`'wght' ${state.weight}, 'ital' ${state.italic}` for (let k in props) {
} if (k in this) {
this[k] = props[k]
}
}
this.update()
},
update() {
let s = document.body.style
s.setProperty(`--weight`, this.weight)
s.setProperty(`--slant`, this.slant)
s.setProperty(`--size`, `${this.size}px`)
// for (let i = 0; i < samples.length; i++) {
// let sample = samples[i]
// // sample.style.fontVariationSettings =
// // `'wght' ${ui.weight}, 'ital' ${ui.slant}`
// sample.style.fontVariationSettings =
// `'wght' ${ui.weight}, 'slnt' ${ui.slant}`
// }
},
} }
function setWeight(weight) { ui.update()
state.weight = weight
updateFontVariationSettings()
}
function setItalic(italic) {
state.italic = italic
updateFontVariationSettings()
}
// monotime() :float milliseconds // monotime() :float milliseconds
// //
@ -133,13 +138,13 @@ function startAnimation() {
return return
} }
weightInput.disabled = true weightInput.disabled = true
italicInput.disabled = true slantInput.disabled = true
isAnimating = true isAnimating = true
let v = 0 let v = 0
let wmin = parseFloat(weightInput.min) let wmin = parseFloat(weightInput.min)
, wmax = parseFloat(weightInput.max) , wmax = parseFloat(weightInput.max)
, imin = parseFloat(italicInput.min) , imin = parseFloat(slantInput.min)
, imax = parseFloat(italicInput.max) , imax = parseFloat(slantInput.max)
, wspeed = 200 // lower is faster; time divisor , wspeed = 200 // lower is faster; time divisor
, ispeed = 800 , ispeed = 800
, clamp = 0.001 , clamp = 0.001
@ -150,15 +155,17 @@ function startAnimation() {
r = (1 + Math.sin((monotime() - startTime) / wspeed)) * 0.5 r = (1 + Math.sin((monotime() - startTime) / wspeed)) * 0.5
v = (wmin * (1 - clamp)) + (((wmax * (1 + clamp)) - (wmin * (1 - clamp))) * r) v = (wmin * (1 - clamp)) + (((wmax * (1 + clamp)) - (wmin * (1 - clamp))) * r)
v = Math.max(wmin, Math.min(wmax, v)) v = Math.max(wmin, Math.min(wmax, v))
setWeight(v) ui.weight = v
weightInput.value = v weightInput.value = v
r = (1 + Math.sin((monotime() - startTime) / ispeed)) * 0.5 r = (1 + Math.sin((monotime() - startTime) / ispeed)) * 0.5
v = (imin * (1 - clamp)) + (((imax * (1 + clamp)) - (imin * (1 - clamp))) * r) v = (imin * (1 - clamp)) + (((imax * (1 + clamp)) - (imin * (1 - clamp))) * r)
v = Math.max(imin, Math.min(imax, v)) v = Math.max(imin, Math.min(imax, v))
setItalic(v) ui.slant = v
italicInput.value = v slantInput.value = v
ui.update()
if (isAnimating) { if (isAnimating) {
requestAnimationFrame(update) requestAnimationFrame(update)
} }
@ -169,28 +176,42 @@ function startAnimation() {
function stopAnimation() { function stopAnimation() {
isAnimating = false isAnimating = false
weightInput.disabled = false weightInput.disabled = false
italicInput.disabled = false slantInput.disabled = false
weightInput.value = String(state.weight) weightInput.value = String(ui.weight)
italicInput.value = String(state.italic) slantInput.value = String(ui.slant)
} }
// UI control: weight slider function bindRangeControl(rangeInput, handler) {
weightInput.addEventListener('input', rangeInput.addEventListener('input',
weightInput.valueAsNumber !== undefined ? ev => { rangeInput.valueAsNumber !== undefined ? ev => {
setWeight(weightInput.valueAsNumber) handler(rangeInput.valueAsNumber)
} : ev => { } : ev => {
setWeight(parseFloat(weightInput.value)) handler(parseFloat(rangeInput.value))
} }
) )
}
// UI control: italic slider // UI controls
italicInput.addEventListener('input', bindRangeControl(weightInput, weight => ui.setState({ weight }) )
italicInput.valueAsNumber !== undefined ? ev => { bindRangeControl(slantInput, slant => ui.setState({ slant }) )
setItalic(italicInput.valueAsNumber) bindRangeControl(sizeInput, size => ui.setState({ size }) )
} : ev => {
setItalic(parseFloat(italicInput.value)) // weightInput.addEventListener('input',
} // weightInput.valueAsNumber !== undefined ? ev => {
) // setWeight(weightInput.valueAsNumber)
// } : ev => {
// setWeight(parseFloat(weightInput.value))
// }
// )
// UI control: slant slider
// slantInput.addEventListener('input',
// slantInput.valueAsNumber !== undefined ? ev => {
// setSlant(slantInput.valueAsNumber)
// } : ev => {
// setSlant(parseFloat(slantInput.value))
// }
// )
// UI control: animate // UI control: animate
var animateInput = document.querySelector('[name="animate"]') var animateInput = document.querySelector('[name="animate"]')

View file

@ -109,7 +109,7 @@ num { /* number */
em, i, .italic { em, i, .italic {
font-style: italic; font-style: italic;
font-variation-settings: 'ital' 100; /*font-variation-settings: 'slnt' 10;*/
} }
small { small {