summaryrefslogtreecommitdiff
path: root/docs/index-var.js
diff options
context:
space:
mode:
authorRasmus Andersson <rasmus@notion.se>2018-10-08 04:32:03 +0300
committerRasmus Andersson <rasmus@notion.se>2018-10-11 09:38:33 +0300
commita0df8aa6d40ab7b1e96dafd93a197c6859580454 (patch)
tree0d1ca583a4ea9cbb2112a114b66698e3a3ed9358 /docs/index-var.js
parentf6050df80182f7bfc55e5f2df7c715969a1cb67d (diff)
downloadinter-a0df8aa6d40ab7b1e96dafd93a197c6859580454.tar.xz
website: big update with samples and vf stuff
Diffstat (limited to 'docs/index-var.js')
-rw-r--r--docs/index-var.js191
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()
+
+
+})();