new v4 website
This commit is contained in:
parent
c2452dee3a
commit
2f9a256e6e
274 changed files with 6316 additions and 330038 deletions
|
|
@ -1,683 +1,17 @@
|
|||
---
|
||||
layout: default
|
||||
title: Dynamic Metrics
|
||||
title: 404 not found
|
||||
custom_html_header: |
|
||||
<link rel="canonical" href="https://d.rsms.me/inter-website/v3/dynmetrics/">
|
||||
<meta name="robots" content="noindex">
|
||||
---
|
||||
{%
|
||||
|
||||
if site.safe == false %}{%
|
||||
assign url_root = "/" %}{% else %}{%
|
||||
assign url_root = "/inter/" %}{% endif %}{%
|
||||
|
||||
for file in site.static_files %}{%
|
||||
assign _path = file.path | remove_first: "/inter" %}{%
|
||||
if _path == "/dynmetrics/index.css" %}{%
|
||||
assign index_css_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/bindings.js" %}{%
|
||||
assign bindings_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
elsif _path == "/res/graphplot.js" %}{%
|
||||
assign graphplot_js_v = file.modified_time | date: "%Y%m%d%H%M%S" %}{%
|
||||
endif %}{%
|
||||
endfor
|
||||
|
||||
%}
|
||||
<link rel="stylesheet" href="index.css?v={{ index_css_v }}">
|
||||
<script src="{{url_root}}res/bindings.js?v={{ bindings_js_v }}"></script>
|
||||
<script src="{{url_root}}res/graphplot.js?v={{ graphplot_js_v }}"></script>
|
||||
|
||||
<div class="row first"><div>
|
||||
<h1>Dynamic Metrics</h1>
|
||||
<div class="row"><div>
|
||||
<h1>404 not found</h1>
|
||||
<p>
|
||||
There's of course no absolute right or wrong when it comes to expressing
|
||||
yourself with typography, but Inter Dynamic Metrics provides guidelines
|
||||
for how to best use Inter.
|
||||
You simply provide the optical font size,
|
||||
and the tracking and line height is calculated for you through the following
|
||||
formula:
|
||||
This page used to exist, but is no longer.<br>
|
||||
</p>
|
||||
<p>
|
||||
<formula>
|
||||
tracking =
|
||||
<const>a</const> + <const>b</const> ×
|
||||
<const title="Base of natural logarithm; ≈2.718">e</const><sup>(<const>c</const> × <const>z</const>)</sup>
|
||||
</formula>
|
||||
<!--formula>
|
||||
line height = <num data-binding="var-l">1.4</num> × <const>z</const>
|
||||
</formula-->
|
||||
<formula title="Values for Inter">
|
||||
<g><const title="Constant a">a</const> = <num data-binding="var-a">-0.0223</num></g>
|
||||
<g><const title="Constant b">b</const> = <num data-binding="var-b">0.185</num></g>
|
||||
<g><const title="Constant c">c</const> = <num data-binding="var-c">-0.1745</num></g>
|
||||
<g><const>z</const> = font size</g>
|
||||
</formula>
|
||||
</p>
|
||||
<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>
|
||||
You can visit an archived version of the old website:
|
||||
<a href="https://d.rsms.me/inter-website/v3/dynmetrics/">https://d.rsms.me/inter-website/v3/dynmetrics/</a>
|
||||
</p>
|
||||
</div></div>
|
||||
|
||||
<div class="white full-width row with-sidebar">
|
||||
|
||||
<div class="samples">
|
||||
<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 spellcheck="false" 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>
|
||||
|
||||
<div class="sidebar controls">
|
||||
|
||||
<div class="control">
|
||||
<img title="Style" class="icon" src="icons/style.svg">
|
||||
<select data-binding="style">
|
||||
<option value="thin">Thin</option>
|
||||
<option value="extra-light">Extra Light</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="regular" default selected>Regular</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="semi-bold">Semi Bold</option>
|
||||
<option value="bold">Bold</option>
|
||||
<option value="extra-bold">Extra Bold</option>
|
||||
<option value="black">Black</option>
|
||||
<option disabled>————————————</option>
|
||||
<option value="thin-italic">Thin Italic</option>
|
||||
<option value="extra-light-italic">Extra Light Italic</option>
|
||||
<option value="light-italic">Light Italic</option>
|
||||
<option value="italic">Italic</option>
|
||||
<option value="medium-italic">Medium Italic</option>
|
||||
<option value="semi-bold-italic">Semi Bold Italic</option>
|
||||
<option value="bold-italic">Bold Italic</option>
|
||||
<option value="extra-bold-italic">Extra Bold Italic</option>
|
||||
<option value="black-italic">Black Italic</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Base tracking" class="icon" src="icons/letter-spacing.svg">
|
||||
<input type="range" min="-0.05" max="0.06" step="0.001" data-binding="base-tracking">
|
||||
<input type="number" min="-0.15" max="1" step="0.001" data-binding="base-tracking">
|
||||
</div>
|
||||
<div class="control">
|
||||
<img title="Line height" class="icon" src="icons/line-height.svg">
|
||||
<input type="range" min="1" max="2" step="0.01" data-binding="var-l">
|
||||
<input type="number" min="1" max="2" step="0.01" data-binding="var-l">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="control">
|
||||
<label title="Constant a">a</label>
|
||||
<input type="range" min="-0.05" max="0" step="0.001" data-binding="var-a">
|
||||
<input type="number" min="-0.05" max="0" step="0.0001" data-binding="var-a">
|
||||
</div>
|
||||
<div class="control">
|
||||
<label title="Constant b">b</label>
|
||||
<input type="range" min="0" max="1" step="0.01" data-binding="var-b">
|
||||
<input type="number" min="0" max="1" step="0.001" data-binding="var-b">
|
||||
</div>
|
||||
<div class="control">
|
||||
<label title="Constant c">c</label>
|
||||
<input type="range" min="-1" max="0" step="0.01" data-binding="var-c">
|
||||
<input type="number" min="-1" max="0" step="0.001" data-binding="var-c">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="control">
|
||||
<label title="Number of ideal matches">ni</label>
|
||||
<input title="Number of ideal matches" type="number" readonly data-binding="ideal-count">
|
||||
<label title="Distance from ideal">di</label>
|
||||
<input title="Distance from ideal" type="number" class="wide" readonly data-binding="ideal-distance">
|
||||
</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>
|
||||
<hr class="without-top-margin">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">(function(){
|
||||
|
||||
// internal variables that are user-controllable, but are not part of
|
||||
// Dynamic Metrics
|
||||
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 = {}
|
||||
var idealValuesList = []
|
||||
var idealValuesTextArea = $('textarea#ideal-values')
|
||||
|
||||
function setIdealValues(valueMap) {
|
||||
idealValues = valueMap
|
||||
idealValuesList = []
|
||||
Object.keys(idealValues).forEach(function(fontSize) {
|
||||
idealValuesList.push([fontSize, idealValues[fontSize]])
|
||||
})
|
||||
if (idealValuesTextArea.value == '') {
|
||||
idealValuesTextArea.value = idealValuesList.map(function(t){
|
||||
return t[0] + '\t' + t[1]
|
||||
}).join('\n')
|
||||
}
|
||||
}
|
||||
|
||||
function parseValues(s) {
|
||||
var values = {}
|
||||
s = s.replace(/^[\s\r\t\n]+|[\s\r\t\n]+$/g, '') // trim whitespace
|
||||
s.split(/\s*\r?\n\s*/).map(function(line) {
|
||||
var t = line.split(/\s+/)
|
||||
if (t.length == 2) {
|
||||
t[0] = parseInt(t[0])
|
||||
t[1] = parseFloat(t[1])
|
||||
values[t[0]] = t[1]
|
||||
}
|
||||
})
|
||||
return values
|
||||
}
|
||||
|
||||
setIdealValues({
|
||||
// // 2018
|
||||
// 6: 0.021,
|
||||
// 7: 0.017,
|
||||
// 8: 0.013,
|
||||
// 9: 0.01,
|
||||
// 10: 0.007,
|
||||
// 11: 0.005,
|
||||
// 12: 0.002,
|
||||
// 13: 0,
|
||||
// 14: -0.002,
|
||||
// 15: -0.004,
|
||||
// 16: -0.005,
|
||||
// 17: -0.007,
|
||||
// 18: -0.008,
|
||||
// 20: -0.01,
|
||||
// 24: -0.013,
|
||||
// 30: -0.016,
|
||||
// 40: -0.02,
|
||||
// 80: -0.02,
|
||||
|
||||
// 2019-02-02
|
||||
// 6: 0.066,
|
||||
// 7: 0.05,
|
||||
// 8: 0.036,
|
||||
// 9: 0.025,
|
||||
// 10: 0.015,
|
||||
// 11: 0.007,
|
||||
// 12: 0,
|
||||
// 13: -0.005,
|
||||
// 14: -0.01,
|
||||
// 15: -0.014,
|
||||
// 16: -0.017,
|
||||
// 17: -0.02,
|
||||
// 18: -0.022,
|
||||
// 20: -0.026,
|
||||
// 24: -0.03,
|
||||
// 30: -0.033,
|
||||
// 40: -0.034,
|
||||
// 80: -0.034,
|
||||
|
||||
// // 2019-02-06
|
||||
// 6: 0.04,
|
||||
// 7: 0.032,
|
||||
// 8: 0.024,
|
||||
// 9: 0.017,
|
||||
// 10: 0.01,
|
||||
// 11: 0.005,
|
||||
// 12: 0,
|
||||
// 13: -0.004,
|
||||
// 14: -0.008,
|
||||
// 15: -0.011,
|
||||
// 16: -0.014,
|
||||
// 17: -0.017,
|
||||
// 18: -0.019,
|
||||
// 20: -0.023,
|
||||
// 24: -0.029,
|
||||
// 30: -0.034,
|
||||
// 40: -0.037,
|
||||
// 80: -0.038,
|
||||
|
||||
// 2019-02-07
|
||||
6: 0.043,
|
||||
7: 0.032,
|
||||
8: 0.024,
|
||||
9: 0.016,
|
||||
10: 0.01,
|
||||
11: 0.005,
|
||||
12: 0,
|
||||
13: -0.0025,
|
||||
14: -0.006,
|
||||
15: -0.009,
|
||||
16: -0.011,
|
||||
17: -0.013,
|
||||
18: -0.014,
|
||||
20: -0.017,
|
||||
24: -0.019,
|
||||
30: -0.021,
|
||||
40: -0.022,
|
||||
80: -0.022,
|
||||
})
|
||||
|
||||
|
||||
// Variables for constants involved in Dynamic Metrics
|
||||
|
||||
// var a = -0.012, b = 0.23, c = -0.21; // di=0.002514 on set-2018-02-18
|
||||
// var a = -0.013, b = 0.251, c = -0.222 // di=0.001742 on set-2018-02-18
|
||||
// var a = -0.015, b = 0.283, c = -0.23; // di=0.00221 on set-2018-02-18
|
||||
// var a = -0.0149, b = 0.298, c = -0.23; // di=0.000484 on set-2018-02-19
|
||||
// var a = -0.018, b = 0.21, c = -0.18; // di=0.000532 on set-2018-02-20
|
||||
// var a = -0.017, b = 0.202, c = -0.175; // 2018-09-28
|
||||
// var a = -0.02, b = 0.0755, c = -0.102 // 2019-02-02
|
||||
// var a = -0.038, b = 0.161, c = -0.12 // 2019-02-06
|
||||
var a = -0.0223, b = 0.185, c = -0.1745 // 2019-02-07
|
||||
|
||||
|
||||
var l = 1.4
|
||||
|
||||
|
||||
// _InterDynamicTracking is a version of InterDynamicTracking that
|
||||
// uses some global variables that are adjustable.
|
||||
//
|
||||
function _InterDynamicTracking(fontSize, weightClass) {
|
||||
// Note: weightClass is currently unused
|
||||
//
|
||||
// y = -0.01021241 + 0.3720623 * e ^ (-0.2808687 * x)
|
||||
// [6-35] 0.05877 .. -0.0101309 (13==0; stops growing around 30-35)
|
||||
// See https://gist.github.com/rsms/8efdbca5f8145a584ed08a7c3d6e5788
|
||||
//
|
||||
return a + b * Math.pow(Math.E, c * fontSize)
|
||||
}
|
||||
|
||||
|
||||
function InterDynamicLineHeight(fontSize, weightClass) {
|
||||
return Math.round(fontSize * l)
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
this.maxBoxWidth = 0
|
||||
this.fontSize = 0
|
||||
this.tracking = 0
|
||||
this.lineHeight = 0
|
||||
this.idealTracking = NPOS
|
||||
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) {
|
||||
return NPOS
|
||||
}
|
||||
return (
|
||||
Math.max(this.tracking, this.idealTracking) -
|
||||
Math.min(this.tracking, this.idealTracking)
|
||||
)
|
||||
}
|
||||
|
||||
Sample.prototype.setFontSize = function(fontSize) {
|
||||
this.fontSize = fontSize
|
||||
this.tracking = baseTracking + _InterDynamicTracking(fontSize, weightClass)
|
||||
this.lineHeight = InterDynamicLineHeight(fontSize, weightClass)
|
||||
this.maxBoxWidth = Math.round(fontSize * (this.tracking + 1) * 25)
|
||||
|
||||
var idealTracking = idealValues[this.fontSize]
|
||||
if (idealTracking === undefined) {
|
||||
if (this.idealTracking != NPOS) {
|
||||
this.diEl.classList.add('unavailable')
|
||||
}
|
||||
this.idealTracking = NPOS
|
||||
this.matchesIdeal = false
|
||||
} else {
|
||||
if (this.idealTracking == NPOS) {
|
||||
this.diEl.classList.remove('unavailable')
|
||||
}
|
||||
this.idealTracking = idealTracking
|
||||
// match to a precision of 3
|
||||
this.matchesIdeal = this.tracking.toFixed(3) == idealTracking.toFixed(3)
|
||||
var di = 1
|
||||
if (this.matchesIdeal) {
|
||||
this.diEl.classList.add('match')
|
||||
} else {
|
||||
this.diEl.classList.remove('match')
|
||||
di = 1 - Math.min(1, this.idealDistance() * 50)
|
||||
}
|
||||
this.diEl.firstChild.style.width = (di * this.maxBoxWidth) + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
Sample.prototype.cssProperties = function() {
|
||||
return [
|
||||
['font-size', round(this.fontSize, 3) + 'px'],
|
||||
['letter-spacing', round(this.tracking, 3) + 'em'],
|
||||
['line-height', round(this.lineHeight, 3) + 'px'],
|
||||
]
|
||||
}
|
||||
|
||||
Sample.prototype.setText = function(text) {
|
||||
this.contentEl.innerText = text
|
||||
this.render()
|
||||
}
|
||||
|
||||
Sample.prototype.render = function() {
|
||||
this.style.fontSize = this.fontSize + 'px'
|
||||
this.style.letterSpacing = this.tracking + 'em'
|
||||
this.style.lineHeight = this.lineHeight + 'px'
|
||||
|
||||
var SP = '\u00A0\u00A0\u00A0'
|
||||
this.infoEl.innerText = (
|
||||
this.fontSize +
|
||||
SP + this.tracking.toFixed(3) +
|
||||
// SP + this.lineHeight.toFixed(3) +
|
||||
(
|
||||
this.idealTracking != NPOS ? (
|
||||
SP + '( ' + this.idealTracking +
|
||||
(this.matchesIdeal ? ' \u2713' : '') +
|
||||
' )'
|
||||
) : ''
|
||||
)
|
||||
)
|
||||
|
||||
this.style.maxWidth = this.maxBoxWidth + 'px'
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
function addChildren(targetNode, children) {
|
||||
targetNode.style.visibility = 'hidden'
|
||||
var i = 0;
|
||||
for (; i < children.length; i++) {
|
||||
targetNode.appendChild(children[i])
|
||||
}
|
||||
targetNode.style.visibility = null
|
||||
}
|
||||
|
||||
function initSamples() {
|
||||
sampleTemplate = $('.sample', samplesEl)
|
||||
samplesEl.removeChild(sampleTemplate)
|
||||
|
||||
// small and medium sizes
|
||||
var i, fontSize = 6, endFontSize = 16
|
||||
for (; fontSize <= endFontSize; fontSize++) {
|
||||
samples.push(new Sample(fontSize))
|
||||
}
|
||||
|
||||
// a few select large samples
|
||||
samples.push(new Sample(17))
|
||||
samples.push(new Sample(18))
|
||||
samples.push(new Sample(20))
|
||||
samples.push(new Sample(24))
|
||||
samples.push(new Sample(30))
|
||||
samples.push(new Sample(40))
|
||||
samples.push(new Sample(80))
|
||||
|
||||
// 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
|
||||
sample.render()
|
||||
}
|
||||
|
||||
function updateSamples() {
|
||||
samples.forEach(updateSample)
|
||||
updateIdealMatches()
|
||||
updateGraphPlot()
|
||||
updateCodeView()
|
||||
}
|
||||
|
||||
function updateIdealMatches() {
|
||||
// ideal-distance
|
||||
var idealCount = 0
|
||||
var distance = 0
|
||||
var ndistances = 0
|
||||
samples.forEach(function(sample) {
|
||||
if (sample.matchesIdeal) {
|
||||
idealCount++
|
||||
}
|
||||
var di = sample.idealDistance()
|
||||
if (di != NPOS) {
|
||||
distance += di
|
||||
ndistances++
|
||||
}
|
||||
})
|
||||
|
||||
distance = distance / ndistances
|
||||
|
||||
bindings.setValue('ideal-distance', distance.toFixed(6))
|
||||
bindings.setValue('ideal-count', idealCount)
|
||||
}
|
||||
|
||||
function updateGraphPlot() {
|
||||
graph.clear()
|
||||
graph.plotLine(idealValuesList, '#0d3')
|
||||
graph.plotf(
|
||||
x => _InterDynamicTracking(x, weightClass),
|
||||
'rgba(0, 0, 0, 0.5)'
|
||||
)
|
||||
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})
|
||||
|
||||
codeOutput.addEventListener('pointerdown', function(ev) {
|
||||
// TODO: don't do this if codeOutput is focused
|
||||
ev.preventDefault()
|
||||
ev.stopPropagation()
|
||||
codeOutput.select()
|
||||
document.execCommand("copy")
|
||||
HUDNotification.show('Copied to clipboard')
|
||||
}, {passive:false,capture:true})
|
||||
|
||||
function updateCodeView() {
|
||||
var s = ''
|
||||
if (focusedSample) {
|
||||
var props = focusedSample.cssProperties()
|
||||
props.forEach(function(prop, i) {
|
||||
var name = prop[0], value = prop[1]
|
||||
s += name + ': ' + value + ';'
|
||||
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()
|
||||
}
|
||||
|
||||
|
||||
bindings.configure('base-tracking', 0, 'float', function (tracking) {
|
||||
baseTracking = tracking
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-a', a, 'float', function (v) {
|
||||
a = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-b', b, 'float', function (v) {
|
||||
b = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-c', c, 'float', function (v) {
|
||||
c = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
bindings.configure('var-l', l, 'float', function (v) {
|
||||
l = v
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
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 = samplesEl.classList
|
||||
cl.remove('font-style-regular')
|
||||
cl.remove('font-style-italic')
|
||||
cl.remove('font-style-medium')
|
||||
cl.remove('font-style-medium-italic')
|
||||
cl.remove('font-style-semi-bold')
|
||||
cl.remove('font-style-semi-bold-italic')
|
||||
cl.remove('font-style-bold')
|
||||
cl.remove('font-style-bold-italic')
|
||||
cl.remove('font-style-extra-bold')
|
||||
cl.remove('font-style-extra-bold-italic')
|
||||
cl.remove('font-style-black')
|
||||
cl.remove('font-style-black-italic')
|
||||
cl.add('font-style-' + style)
|
||||
weightClass = (
|
||||
style.indexOf('black') != -1 ? 900 :
|
||||
style.indexOf('bold') != -1 ? 700 :
|
||||
style.indexOf('medium') != -1 ? 500 :
|
||||
400
|
||||
)
|
||||
updateSamples()
|
||||
})
|
||||
|
||||
|
||||
bindings.bindAllInputs('[data-binding]')
|
||||
|
||||
// double-click base tracking to reset
|
||||
$('input[type="range"][data-binding="base-tracking"]').addEventListener(
|
||||
'dblclick',
|
||||
function(ev) { bindings.setValue('base-tracking', 0) }
|
||||
)
|
||||
|
||||
;[
|
||||
['var-a',a],
|
||||
['var-b',b],
|
||||
['var-c',c],
|
||||
['var-l',l],
|
||||
['base-tracking', 0]
|
||||
].forEach(p => {
|
||||
let bindname = p[0], defval = p[1]
|
||||
$$('input[type="range"][data-binding="'+bindname+'"]').forEach(e => {
|
||||
e.addEventListener('dblclick', ev =>
|
||||
bindings.setValue(bindname, defval))
|
||||
})
|
||||
})
|
||||
|
||||
// allow editing of ideal values
|
||||
idealValuesTextArea.addEventListener('input', function(ev) {
|
||||
setIdealValues(parseValues(idealValuesTextArea.value))
|
||||
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()
|
||||
updateSamples()
|
||||
|
||||
})();</script>
|
||||
|
|
|
|||
Reference in a new issue