diff options
author | Rasmus Andersson <rasmus@notion.se> | 2018-10-08 04:32:03 +0300 |
---|---|---|
committer | Rasmus Andersson <rasmus@notion.se> | 2018-10-11 09:38:33 +0300 |
commit | a0df8aa6d40ab7b1e96dafd93a197c6859580454 (patch) | |
tree | 0d1ca583a4ea9cbb2112a114b66698e3a3ed9358 /docs/index-var.js | |
parent | f6050df80182f7bfc55e5f2df7c715969a1cb67d (diff) | |
download | inter-a0df8aa6d40ab7b1e96dafd93a197c6859580454.tar.xz |
website: big update with samples and vf stuff
Diffstat (limited to 'docs/index-var.js')
-rw-r--r-- | docs/index-var.js | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/docs/index-var.js b/docs/index-var.js new file mode 100644 index 000000000..93cd05e97 --- /dev/null +++ b/docs/index-var.js @@ -0,0 +1,191 @@ +(function(){ + +var root = document.querySelector('div.variable') +var sample = document.querySelector('.variable-sample') +var animateCheckbox = document.querySelector('[name="animate"]') + + +var ui = { + state: { + weight: 0, + slant: 0, + size: 0, // px + letterSpacing: 0, // em + lineHeight: 0, + }, + + variable: { + weight: true, + slant: true, + }, + + formatters: { + size(v) { return `${v}px` }, + letterSpacing(v) { return `${v}em` }, + }, + + inputs: { + // populated by init() + }, + + init() { + let s = getComputedStyle(sample) + + // We test for variable-font support by, in CSS, conditionally using + // a different font family name when VF is supported. Then we test for + // what font family name is in effect. If it's the "var" one, we can be + // fairly certain that variable fonts are supported by the user agent. + let supportsVF = s.fontFamily.indexOf('Inter UI var') != -1 + // supportsVF = false // XXX + + // hook up input controls + for (let k in this.state) { + let value = parseFloat(s.getPropertyValue(`--var-${k}`)) + this.state[k] = value + let input = root.querySelector(`[name="${k}"]`) + if (input) { + this.inputs[k] = input + input.value = value + if (!supportsVF && this.variable[k]) { + input.disabled = true + input.parentElement.classList.add('disabled') + } else if (input.type == 'range') { + this.bindRangeControl(input, v => { + this.state[k] = v + this.update() + }) + } + } + } + + if (!supportsVF) { + animateCheckbox.disabled = true + animateCheckbox.parentElement.classList.add('disabled') + let unsupportedMessage = root.querySelector(`.unsupported-message`) + if (unsupportedMessage) { + unsupportedMessage.classList.add('active') + } + } + }, + + bindRangeControl(rangeInput, handler) { + rangeInput.addEventListener('input', + rangeInput.valueAsNumber !== undefined ? ev => { + handler(rangeInput.valueAsNumber) + } : ev => { + handler(parseFloat(rangeInput.value)) + } + ) + }, + + setState(props) { + for (let k in props) { + if (k in this.state) { + this.state[k] = props[k] + } + } + this.update() + }, + + update() { + let s = sample.style + for (let k in this.state) { + let f = this.formatters[k] + s.setProperty(`--var-${k}`, f ? f(this.state[k]) : this.state[k]) + } + }, +} + + +// 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 + } + ui.inputs.weight.disabled = true + ui.inputs.slant.disabled = true + isAnimating = true + let v = 0 + let wmin = parseFloat(ui.inputs.weight.min) + , wmax = parseFloat(ui.inputs.weight.max) + , imin = parseFloat(ui.inputs.slant.min) + , imax = parseFloat(ui.inputs.slant.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)) + ui.state.weight = v + ui.inputs.weight.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)) + ui.state.slant = v + ui.inputs.slant.value = v + + ui.update() + + if (isAnimating) { + requestAnimationFrame(update) + } + } + update() +} + +function stopAnimation() { + isAnimating = false + ui.inputs.weight.disabled = false + ui.inputs.slant.disabled = false + ui.inputs.weight.value = String(ui.state.weight) + ui.inputs.slant.value = String(ui.state.slant) +} + +// UI control: animate +if (!window.requestAnimationFrame) { + animateCheckbox.disabled = true + animateCheckbox.title = "Not supported by browser" +} else { + animateCheckbox.addEventListener('change', ev => { + if (animateCheckbox.checked) { + startAnimation() + } else { + stopAnimation() + } + }) +} + +// UI control: invert colors ("Black/White") +document.querySelector('[name="invert"]').addEventListener('change', ev => { + if (ev.target.checked) { + sample.parentElement.classList.add('black') + sample.parentElement.classList.remove('white') + } else { + sample.parentElement.classList.remove('black') + sample.parentElement.classList.add('white') + } +}) + + +ui.init() + + +})(); |