SPL Meter: measure the room, not just watch it #10
@@ -196,6 +196,38 @@ function readoutView(root, moduleApi) {
|
|||||||
const unit = root.querySelector('.spl-unit');
|
const unit = root.querySelector('.spl-unit');
|
||||||
const sub = root.querySelector('.spl-sub');
|
const sub = root.querySelector('.spl-sub');
|
||||||
const box = root.querySelector('.spl-readout');
|
const box = root.querySelector('.spl-readout');
|
||||||
|
const value = root.querySelector('.spl-value');
|
||||||
|
let fitKey = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grow the number until it fills the tile, measuring the text we actually
|
||||||
|
* have rather than assuming a digit count.
|
||||||
|
*
|
||||||
|
* The CSS can only guess at width — it has to pick a cqw coefficient for
|
||||||
|
* some number of characters, and then "-100.5" overflows the tile that
|
||||||
|
* "-45.9" merely filled. Measuring costs one layout read, and only when
|
||||||
|
* the tile size or the length of the reading changes.
|
||||||
|
*/
|
||||||
|
function fit() {
|
||||||
|
const w = root.clientWidth, h = root.clientHeight;
|
||||||
|
const key = `${w}x${h}:${num.textContent.length}:${unit.textContent}`;
|
||||||
|
if (key === fitKey || w < 2 || h < 2) return;
|
||||||
|
fitKey = key;
|
||||||
|
|
||||||
|
const TRIAL = 100;
|
||||||
|
num.style.fontSize = `${TRIAL}px`;
|
||||||
|
unit.style.fontSize = `${TRIAL * 0.26}px`;
|
||||||
|
const natural = value.scrollWidth || 1;
|
||||||
|
|
||||||
|
// Leave the caption its room when it is showing, and a little air either
|
||||||
|
// way so descenders and the tile's padding never clip.
|
||||||
|
const subH = sub.offsetParent ? sub.getBoundingClientRect().height + 6 : 0;
|
||||||
|
const byHeight = (h - subH) * 0.92;
|
||||||
|
const byWidth = ((w - 8) * TRIAL) / natural;
|
||||||
|
const size = Math.max(12, Math.min(byHeight, byWidth));
|
||||||
|
num.style.fontSize = `${size}px`;
|
||||||
|
unit.style.fontSize = `${size * 0.26}px`;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
render(payload) {
|
render(payload) {
|
||||||
@@ -205,6 +237,7 @@ function readoutView(root, moduleApi) {
|
|||||||
num.textContent = '––.–';
|
num.textContent = '––.–';
|
||||||
sub.textContent = payload && payload.error ? payload.error : '';
|
sub.textContent = payload && payload.error ? payload.error : '';
|
||||||
box.dataset.level = 'idle';
|
box.dataset.level = 'idle';
|
||||||
|
fit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const value = readValue(ch, s);
|
const value = readValue(ch, s);
|
||||||
@@ -225,8 +258,9 @@ function readoutView(root, moduleApi) {
|
|||||||
if (ch.clip) parts.push('CLIP');
|
if (ch.clip) parts.push('CLIP');
|
||||||
if (!payload.calibrated) parts.push('uncalibrated');
|
if (!payload.calibrated) parts.push('uncalibrated');
|
||||||
sub.textContent = parts.join(' · ');
|
sub.textContent = parts.join(' · ');
|
||||||
|
fit();
|
||||||
},
|
},
|
||||||
resize() {},
|
resize() { fitKey = ''; fit(); },
|
||||||
destroy() { root.innerHTML = ''; },
|
destroy() { root.innerHTML = ''; },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "spl-meter",
|
"id": "spl-meter",
|
||||||
"name": "SPL Meter",
|
"name": "SPL Meter",
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"proddash": ">=1.5.0",
|
"proddash": ">=1.5.0",
|
||||||
"description": "Calibrated sound level, Leq and RTA from an audio input on this machine",
|
"description": "Calibrated sound level, Leq and RTA from an audio input on this machine",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
|||||||
@@ -30,18 +30,19 @@
|
|||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sized off the tile, so one cell and six cells both read well. Height has
|
/* A first-paint size only. client.js measures the text and sets the real
|
||||||
to be in the min() as well as width: a 2x1 tile is wide and short, and
|
one inline, because CSS has to assume a digit count and gets it wrong the
|
||||||
sizing on width alone pushes the digits straight out through the top. */
|
moment the reading needs a sixth character: the coefficient that fills a
|
||||||
|
tile for "-45.9" pushes "-100.5" straight out through the side. */
|
||||||
[data-module="spl-meter"] .spl-num {
|
[data-module="spl-meter"] .spl-num {
|
||||||
font-size: clamp(1.25rem, min(20cqw, 42cqh), 6rem);
|
font-size: clamp(1.25rem, min(26cqw, 60cqh), 100rem);
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-module="spl-meter"] .spl-unit {
|
[data-module="spl-meter"] .spl-unit {
|
||||||
font-size: clamp(0.65rem, min(6cqw, 13cqh), 1.5rem);
|
font-size: clamp(0.65rem, min(7cqw, 15cqh), 26rem);
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user