inter/docs/lab/var.html

256 lines
No EOL
6.3 KiB
HTML

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="../inter.css" rel="stylesheet">
<style type="text/css">
:root {
--weight: 400;
--slant: 0;
--size: 80px;
}
@font-face {
font-family: 'Inter-var-x';
font-weight: 100 900;
font-style: oblique 0deg 10deg;
src: url('fonts/var/Inter.var.woff2') format("woff2"),
url('../font-files/Inter.var.woff2') format("woff2");
}
html {
font-family: 'Inter', sans-serif;
font-size: 14px;
letter-spacing: 0;
}
@supports (font-variation-settings: normal) {
html {
font-family: 'Inter-var-x', sans-serif;
}
}
body {
margin: 0;
padding: 0;
}
.sample {
padding: 40px 40px 40px 35px;
font-size: var(--size);
letter-spacing: -0.03em;
font-family: 'Inter-var-x', "Adobe NotDef";
font-variation-settings: 'wght' var(--weight), 'slnt' calc(-1 * var(--slant));
outline: none;
}
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="100" max="900" name="weight"></label>
<label>Slant: <input type="range" value="0" min="0" max="10" step="0.01" name="slant"></label>
<label>Size: <input type="range" value="96" min="6" max="400" name="size"></label>
<select name="animate">
<option value="" default>Animation: off</option>
<option value="weight">Animation: weight</option>
<option value="slant">Animation: slant</option>
<option value="weight,slant">Animation: weight &amp; slant</option>
</select>
<select name="align">
<option value="left" default>Align: left</option>
<option value="center">Align: center</option>
<option value="right">Align: right</option>
</select>
</div>
<div class="sample" contenteditable autocomplete="off" spellcheck="false">
Inter Typeface Family<br>
Variable weight axis<br>
Variable slant/oblique axis<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
abcdefghijklmnopqrstuvwxyz<br>
1234567890?!()[]{}&*^%$#@~&lt;&gt;<br>
</div>
<script type="text/javascript">
var samples = document.querySelectorAll('div.sample')
var weightInput = document.querySelector('[name="weight"]')
var slantInput = document.querySelector('[name="slant"]')
var sizeInput = document.querySelector('[name="size"]')
var ui = {
weight: parseFloat(weightInput.value),
slant: parseFloat(slantInput.value),
size: parseFloat(sizeInput.value),
setState(props) {
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}`
// }
},
}
ui.update()
// 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()
}
)
// animation state
var isAnimating = false
var animateWeight = false
var animateSlant = false
function startAnimation(animateAxes) {
animateWeight = animateAxes.indexOf('weight') != -1
animateSlant = animateAxes.indexOf('slant') != -1
weightInput.disabled = animateWeight
slantInput.disabled = animateSlant
if (isAnimating) {
return
}
if (!animateWeight && !animateSlant) {
throw new Error('!animateWeight && !animateSlant')
stopAnimation()
}
isAnimating = true
let v = 0
let wmin = parseFloat(weightInput.min)
, wmax = parseFloat(weightInput.max)
, imin = parseFloat(slantInput.min)
, imax = parseFloat(slantInput.max)
, wspeed = 800 // lower is faster; time divisor
, ispeed = 600
, clamp = 0.001
, startTime = monotime()
function update() {
let r = 0, v = 0
if (animateWeight) {
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))
ui.weight = v
weightInput.value = v
}
if (animateSlant) {
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))
ui.slant = v
slantInput.value = v
}
ui.update()
if (isAnimating) {
requestAnimationFrame(update)
}
}
update()
}
function stopAnimation() {
isAnimating = false
weightInput.disabled = false
slantInput.disabled = false
weightInput.value = String(ui.weight)
slantInput.value = String(ui.slant)
}
function bindRangeControl(rangeInput, handler) {
rangeInput.addEventListener('input',
rangeInput.valueAsNumber !== undefined ? ev => {
handler(rangeInput.valueAsNumber)
} : ev => {
handler(parseFloat(rangeInput.value))
}
)
}
// UI controls
bindRangeControl(weightInput, weight => ui.setState({ weight }) )
bindRangeControl(slantInput, slant => ui.setState({ slant }) )
bindRangeControl(sizeInput, size => ui.setState({ size }) )
// UI control: alignment
var alignInput = document.querySelector('[name="align"]')
var updateAlignment = function() {
for (let s of samples) {
s.style.textAlign = alignInput.value
}
}
alignInput.addEventListener('change', updateAlignment)
updateAlignment()
// UI control: animate
var animateInput = document.querySelector('[name="animate"]')
if (!window.requestAnimationFrame) {
animateInput.disabled = true
} else {
animateInput.addEventListener('change', ev => {
if (animateInput.value.length == 0) {
stopAnimation()
} else {
console.log('x', animateInput.value.split(','))
startAnimation(animateInput.value.split(','))
}
})
}
</script>
</body>
</html>