web: VF: slant axis instead of italic axis
This commit is contained in:
parent
3fba02c38a
commit
6f6f6683ed
5 changed files with 119 additions and 98 deletions
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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?!()[]{}&*^%$#@~<><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"]')
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Reference in a new issue