mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-23 05:11:34 +00:00
82 lines
3.8 KiB
JavaScript
82 lines
3.8 KiB
JavaScript
/**
|
||
* Default (gauge) tuner visualization for the Slopsmith tuner plugin.
|
||
*
|
||
* Contract: window._tunerViz_default(container) → { update(note, cents, freq), destroy() }
|
||
* - note: string | null (null = no signal)
|
||
* - cents: number (deviation from target, −50…+50)
|
||
* - freq: number (detected frequency in Hz)
|
||
*/
|
||
window._tunerViz_default = function (container) {
|
||
'use strict';
|
||
|
||
// ── DOM ───────────────────────────────────────────────────────────
|
||
const noteDisplay = document.createElement('div');
|
||
noteDisplay.className = 'my-2 h-16 flex items-center justify-center';
|
||
|
||
const noteText = document.createElement('div');
|
||
noteText.className = 'text-5xl font-black text-white';
|
||
noteText.textContent = '--';
|
||
noteDisplay.appendChild(noteText);
|
||
container.appendChild(noteDisplay);
|
||
|
||
const freqDisplay = document.createElement('div');
|
||
freqDisplay.className = 'text-xs text-gray-500 mb-3 font-mono text-center w-full';
|
||
freqDisplay.textContent = '0.0 Hz';
|
||
container.appendChild(freqDisplay);
|
||
|
||
const gaugeEl = document.createElement('div');
|
||
gaugeEl.className = 'w-full h-2.5 bg-dark-900 border border-gray-800 rounded-full relative overflow-hidden mb-1.5';
|
||
|
||
const centerMarker = document.createElement('div');
|
||
centerMarker.className = 'absolute left-1/2 top-0 bottom-0 w-0.5 bg-accent z-10';
|
||
gaugeEl.appendChild(centerMarker);
|
||
|
||
const gaugeNeedle = document.createElement('div');
|
||
gaugeNeedle.className = 'absolute left-1/2 top-0 bottom-0 w-1 bg-white transition-all duration-100 ease-out -translate-x-1/2 z-20 shadow-[0_0_8px_rgba(255,255,255,0.5)]';
|
||
gaugeEl.appendChild(gaugeNeedle);
|
||
container.appendChild(gaugeEl);
|
||
|
||
const centsDisplay = document.createElement('div');
|
||
centsDisplay.className = 'text-sm font-bold tracking-tight text-center w-full';
|
||
centsDisplay.textContent = '0 cents';
|
||
container.appendChild(centsDisplay);
|
||
|
||
// ── Public API ────────────────────────────────────────────────────
|
||
function update(note, cents, freq) {
|
||
if (note === null) {
|
||
noteText.textContent = '--';
|
||
noteText.className = 'text-5xl font-black text-white';
|
||
freqDisplay.textContent = '0.0 Hz';
|
||
centsDisplay.textContent = '0 cents';
|
||
gaugeNeedle.style.left = '50%';
|
||
gaugeNeedle.className = 'absolute left-1/2 top-0 bottom-0 w-1 bg-white transition-all duration-100 ease-out -translate-x-1/2 z-20 shadow-[0_0_8px_rgba(255,255,255,0.5)]';
|
||
return;
|
||
}
|
||
|
||
noteText.textContent = note;
|
||
noteText.className = 'text-5xl font-black ' + (Math.abs(cents) < 5 ? 'text-green-400' : 'text-white');
|
||
|
||
freqDisplay.textContent = freq.toFixed(1) + ' Hz';
|
||
centsDisplay.textContent = (cents > 0 ? '+' : '') + cents.toFixed(0) + ' cents';
|
||
|
||
const gaugeRange = 50;
|
||
const percent = Math.max(0, Math.min(100, 50 + (cents / gaugeRange) * 50));
|
||
gaugeNeedle.style.left = percent + '%';
|
||
|
||
if (Math.abs(cents) < 5) {
|
||
gaugeNeedle.className = 'absolute top-0 bottom-0 w-1 bg-green-400 transition-all duration-100 ease-out -translate-x-1/2 z-20 shadow-[0_0_8px_rgba(74,222,128,0.5)]';
|
||
} else {
|
||
gaugeNeedle.className = 'absolute top-0 bottom-0 w-1 bg-white transition-all duration-100 ease-out -translate-x-1/2 z-20 shadow-[0_0_8px_rgba(255,255,255,0.5)]';
|
||
}
|
||
}
|
||
|
||
function destroy() {
|
||
noteDisplay.remove();
|
||
freqDisplay.remove();
|
||
gaugeEl.remove();
|
||
centsDisplay.remove();
|
||
}
|
||
|
||
return { update, destroy };
|
||
};
|