diff options
author | Rasmus Andersson <rasmus@notion.se> | 2018-02-21 05:12:29 +0300 |
---|---|---|
committer | Rasmus Andersson <rasmus@notion.se> | 2018-02-21 05:46:59 +0300 |
commit | bd425b8fb85efebfae31e45b0c30b521ecd82a79 (patch) | |
tree | 345e94e3ffa009268676e1df09c06c03ea7f2b88 | |
parent | edfd4883002ec944c92bbf98a7a51f2629efc879 (diff) | |
download | inter-bd425b8fb85efebfae31e45b0c30b521ecd82a79.tar.xz |
website: dynamic metrics
-rw-r--r-- | docs/dynmetrics/index.css | 62 | ||||
-rw-r--r-- | docs/dynmetrics/index.html | 140 | ||||
-rw-r--r-- | docs/res/base.css | 6 | ||||
-rw-r--r-- | docs/samples/index.css | 1 |
4 files changed, 172 insertions, 37 deletions
diff --git a/docs/dynmetrics/index.css b/docs/dynmetrics/index.css index a888258c2..bf21139ce 100644 --- a/docs/dynmetrics/index.css +++ b/docs/dynmetrics/index.css @@ -34,6 +34,7 @@ formula { overflow: hidden; margin-right: 1em; margin-bottom: 1em; + white-space: nowrap; } .row.white formula { background: #f5f5f5; @@ -49,6 +50,9 @@ formula.code { formula > * { margin: 0 0.2em 0 0.2em; } + formula > g { + display: inline-block; + } formula > const { margin-bottom: 0.11em; } @@ -63,17 +67,28 @@ formula.code { overflow: auto; overflow-wrap: break-word; word-break: break-word; + padding: 50px 0 0 50px; /* note: samples have 50px right margin */ } .samples .sample { - /*background: lightpink;*/ color: #111; flex: 0 1 auto; outline: none; margin-right: 50px; margin-bottom: 50px; } - .samples .sample .di { + .samples .sample > * { display: block; + outline: none; + } + .samples .sample .content { + padding-left: 10px; + border-left: 2px solid transparent; + margin-left: -12px; + } + .samples .sample.selected .content { + border-left-color: rgb(45, 143, 255); + } + .samples .sample .di { background-color: #ccc; height: 1px; width: 100%; @@ -118,7 +133,6 @@ formula.code { } .row.with-sidebar > *:first-child { flex: 1 1 auto; - padding: 50px 0 0 50px; /* note: samples have 50px right margin */ } .row.with-sidebar > .sidebar { flex: 0 0 auto; @@ -159,9 +173,17 @@ div.controls > h3 { div.controls > textarea { border: none; padding:16px; - height: 400px; + height: 220px; font-family: "SFMono-Regular", Menlo, Consolas, Inconsolata, monospace; outline: none; + resize: vertical; + color: #999; +} +div.controls > textarea:focus { + color: inherit; +} +div.controls textarea#code-output { + height: 50px; } div.controls .control > * { /*max-width: 50%;*/ @@ -229,20 +251,19 @@ div.controls .control > label { div.controls canvas { height: 200px; } +div.controls .when-selection { + display: none; +} +div.controls.has-selected-sample .when-selection { + display: block; +} -.row.small-window { +.row.narrow-window { margin-top:0; padding-top:0; } -@media only screen and (min-width: 541px) { - .small-window { - display: none; - } -} - -@media only screen and (max-width: 540px) { - +@media only screen and (max-width: 565px) { .row.with-sidebar { overflow: auto; } @@ -250,15 +271,16 @@ div.controls canvas { div.controls { display: none; } - div.controls .graphplot, - div.controls hr.without-top-margin, - div.controls h3, - div.controls #ideal-values - { - display: none; - } .row.with-sidebar { flex-direction: column; } } + +/* small devices (<= iPhone 6+) */ +@media only screen and (max-device-width: 414px) { + .samples { + padding-left: 20px; + padding-right: 50px; + } +} diff --git a/docs/dynmetrics/index.html b/docs/dynmetrics/index.html index ba60cdce6..24ace9ad3 100644 --- a/docs/dynmetrics/index.html +++ b/docs/dynmetrics/index.html @@ -30,9 +30,9 @@ endfor <p> There's of course no absolute right or wrong when it comes to expressing yourself with typography, but Inter UI Dynamic Metrics provides guidelines - for <em>good</em> typography. - You simply provide the optical font size, and the tracking and leading - (letter spacing and line height) will be calculated using the following + for how to best use Inter UI. + You simply provide the optical font size, + and the tracking and leading is calculated for you through the following formula: </p> <p> @@ -44,31 +44,34 @@ endfor <formula> leading = <num>1.4</num> × fontSize </formula> - <formula> - <const title="Constant a">a</const> = <num data-binding="var-a">-0.016</num> - <const title="Constant b">b</const> = <num data-binding="var-b">0.21</num> - <const title="Constant c">c</const> = <num data-binding="var-c">-0.18</num> - <const title="Base of natural logarithm">e</const> ≈ <num>2.718</num> + <formula title="Values for Inter UI"> + <g><const title="Constant a">a</const> = <num data-binding="var-a">-0.016</num></g> + <g><const title="Constant b">b</const> = <num data-binding="var-b">0.21</num></g> + <g><const title="Constant c">c</const> = <num data-binding="var-c">-0.18</num></g> + <g class="wide-window"><const title="Base of natural logarithm">e</const> ≈ <num>2.718</num></g> </formula> </p> - <p class="small-window"> + <p class="wide-window"> + The controls below can be used to play around with the + <const>a</const>, <const>b</const> and <const>c</const> constants to discover + how they affect tracking. + </p> + <p class="narrow-window"> <small>View this on a larger screen to enable interactive control.</small> </p> </div></div> -<!-- <div class="row small-window"><div> - Hello -</div></div> --> - <div class="white full-width row with-sidebar"> <div class="samples"> - <p contenteditable class="sample"> + <p class="sample"> <span class="di"><span></span></span> <span class="info" title="size, tracking, (ideal tracking) — progress bar shows distance from ideal" >15 0.0 ( 0.0 )</span> + <span contenteditable class="content"> Such a riot of sea and wind strews the whole extent of beach with whatever has been lost or thrown overboard, or torn out of sunken ships. Many a man has made a good week’s work in a single day by what he has found while walking along the Beach when the surf was down. + </span> </p> </div> @@ -121,6 +124,11 @@ endfor </div> <hr class="without-bottom-margin"> <canvas class="graphplot">Canvas not Supported</canvas> + + <hr class="when-selection without-top-margin"> + <h3 class="when-selection">CSS</h3> + <textarea class="when-selection" readonly id="code-output"></textarea> + <hr class="without-top-margin"> <h3>Ideal values</h3> <textarea id="ideal-values"></textarea> @@ -137,6 +145,10 @@ endfor var baseTracking = 0 var weightClass = 400 +function round(num, prec) { + return parseFloat(num.toFixed(prec)) +} + // Ideal values designed one by one, by hand. // font size => tracking var idealValues = {} @@ -267,6 +279,7 @@ var NPOS = Number.MAX_SAFE_INTEGER function Sample(fontSize) { this.rootEl = sampleTemplate.cloneNode(true) this.infoEl = $('.info', this.rootEl) + this.contentEl = $('.content', this.rootEl) this.diEl = $('.di', this.rootEl) this.diEl.classList.add('unavailable') this.style = this.rootEl.style @@ -278,8 +291,24 @@ function Sample(fontSize) { this.matchesIdeal = false this.setFontSize(fontSize) this.render() + + // listen for focus events on the editable content + var s = this + this.contentEl.addEventListener( + 'focus', + function(){ s.onReceivedFocus() }, + {passive:true, capture:false} + ) + this.contentEl.addEventListener( + 'blur', + function(){ s.onLostFocus() }, + {passive:true, capture:false} + ) } +Sample.prototype.onReceivedFocus = function() {} +Sample.prototype.onLostFocus = function() {} + Sample.prototype.idealDistance = function(fontSize) { // returns the distance from the ideal (or NPOS if no "ideal" data available) if (this.idealTracking == NPOS) { @@ -322,6 +351,14 @@ Sample.prototype.setFontSize = function(fontSize) { } } +Sample.prototype.cssProperties = function() { + return { + fontSize: round(this.fontSize, 3) + 'px', + letterSpacing: round(this.tracking, 3) + 'em', + lineHeight: round(this.lineHeight, 3) + 'px', + } +} + Sample.prototype.render = function() { this.style.fontSize = this.fontSize + 'px' this.style.letterSpacing = this.tracking + 'em' @@ -346,8 +383,10 @@ Sample.prototype.render = function() { var bindings = new Bindings() +var samplesEl = $('.samples') var sampleTemplate var samples = [] // Sample[] +var focusedSample = null // Sample | null var graph = new GraphPlot($('canvas.graphplot')) graph.setOrigin(-0.2, 0.8) graph.setScale(0.049, 5) @@ -362,7 +401,6 @@ function addChildren(targetNode, children) { } function initSamples() { - var samplesEl = $('.samples') sampleTemplate = $('.sample', samplesEl) samplesEl.removeChild(sampleTemplate) @@ -380,10 +418,28 @@ function initSamples() { samples.push(new Sample(30)) samples.push(new Sample(40)) + // connect focus events + var onSampleReceivedFocus = function() { setSelectedSample(this) } + samples.forEach(function(s) { + s.onReceivedFocus = onSampleReceivedFocus + }) + // add to dom in one go addChildren(samplesEl, samples.map(function(s) { return s.rootEl })) } +function setSelectedSample(sample) { + if (focusedSample !== sample) { + if (focusedSample) { + focusedSample.rootEl.classList.remove('selected') + } + if (sample) { + sample.rootEl.classList.add('selected') + } + focusedSample = sample + updateSelection() + } +} function updateSample(sample) { sample.setFontSize(sample.fontSize) // updates derived values @@ -394,6 +450,7 @@ function updateSamples() { samples.forEach(updateSample) updateIdealMatches() updateGraphPlot() + updateCodeView() } function updateIdealMatches() { @@ -424,6 +481,46 @@ function updateGraphPlot() { graph.plotf(function(x) { return InterUIDynamicTracking(x, weightClass) }) + if (focusedSample) { + var graphedFontSize = Math.min(24, focusedSample.fontSize) // clamp to [-inf,24] + graph.plotPoints([ + [graphedFontSize, focusedSample.tracking] + ], 'rgb(45, 143, 255)') + } +} + +var codeOutput = $('#code-output') +codeOutput.addEventListener('focus', function(ev) { + ev.preventDefault() + ev.stopPropagation() + codeOutput.select() +}, {passive:false,capture:true}) + +function updateCodeView() { + var s = '' + if (focusedSample) { + var cssprops = focusedSample.cssProperties() + var props = Object.keys(cssprops) + props.forEach(function(prop, i) { + s += prop + ': ' + cssprops[prop] + ';' + if (i != props.length-1) { + s += '\n' + } + }) + } + codeOutput.value = s +} + +function updateSelection() { + var controlsEl = $('.controls') + if (focusedSample) { + controlsEl.classList.add('has-selected-sample') + } else { + controlsEl.classList.remove('has-selected-sample') + } + + updateGraphPlot() + updateCodeView() } @@ -456,7 +553,7 @@ bindings.configure('ideal-count', 0, 'int', function (v) {}) bindings.configure('ideal-distance', 0, 'float', function (v) {}) bindings.configure('style', null, null, function (style) { - var cl = $('.samples').classList + var cl = samplesEl.classList cl.remove('font-style-regular') cl.remove('font-style-italic') cl.remove('font-style-medium') @@ -490,6 +587,17 @@ idealValuesTextArea.addEventListener('input', function(ev) { updateSamples() }) +// listen for clicks onto "background", to deselect any selected sample +document.body.addEventListener('pointerdown', function(ev){ + if ( + ev.target === document.body || + ev.target === samplesEl || + ev.target.classList && ev.target.classList.contains('row') + ) { + setSelectedSample(null) + } +}) + // start initSamples() diff --git a/docs/res/base.css b/docs/res/base.css index 5cc6cc39d..bf0c440b7 100644 --- a/docs/res/base.css +++ b/docs/res/base.css @@ -470,8 +470,14 @@ box h3 { /* ------------------------------------------------------ */ +/* wide windows */ +@media only screen and (min-width: 566px) { + .narrow-window { display: none; } +} + /* narrow windows */ @media only screen and (max-width: 565px) { + .wide-window { display: none; } .row.menu ul { justify-content: space-between; } diff --git a/docs/samples/index.css b/docs/samples/index.css index bbd7bb478..4711dff69 100644 --- a/docs/samples/index.css +++ b/docs/samples/index.css @@ -19,7 +19,6 @@ livesample { margin-bottom: 1.6em; } livesample:hover { - /*color: rgb(3, 102, 214);*/ border-left-color: rgb(3, 102, 214); } livesample:focus { |