Panel, le cockpit d'instruments pour interfaces web

Instruments de mesure et contrôles inspirés des consoles de studio, des cockpits analogiques et des tableaux de bord vintage.
Cadrans, oscilloscope, radar, potentiomètres et interrupteurs en Canvas, CSS et JavaScript natifs, pilotés par API, sans dépendance.

  • ✓Zéro dépendance
  • ✓Canvas pilotable par API
  • ✓Composants synchronisables
  • ✓Temps réel : WebSocket, SSE
Vanilla JS IIFE ESM 19 ko gz MIT Souverain Vintage
panel-api.js → new SXP.Panel.Gauge()
// 1. un cadran à aiguille sur un <canvas> const bar = new SXP.Panel.Gauge("#pression", { min: 0, max: 10, unit: "bar" }); // 2. piloté par API, depuis n'importe quelle source socket.onmessage = e => bar.set(+e.data);
0 dépendance HTML / CSS / JS natif Canvas pilotable API JavaScript Composants synchronisables Compatible WebSocket Animations temps réel Responsive

🎛️ Pourquoi Panel ?

Panel est un SDK front-end d'instruments interactifs et de composants de contrôle, pas un thème graphique ni une simple collection de widgets. Chaque élément repose sur du Canvas, du CSS et du JavaScript natif, se pilote par API, se synchronise avec les autres composants, fonctionne sans dépendance externe et réagit en temps réel.

Conçu pour les cockpits, consoles audio, tableaux de bord industriels, outils métiers, simulateurs et laboratoires, Panel donne aux interfaces professionnelles une couche de contrôle précise, lisible et souveraine. Développé par SynapxLab, il s'inscrit dans une solution libre, hébergée en France, sans dépendance aux GAFA.

// npm
npm install @synapxlab/panel

<!-- script global (IIFE) : window.SXP.Panel + window.SxpPanel, un seul fichier, 19 ko gz -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@synapxlab/panel/dist/panel.css">
<script src="https://cdn.jsdelivr.net/npm/@synapxlab/panel/dist/panel.min.js"></script>

// module ES
import Panel from '@synapxlab/panel';
import '@synapxlab/panel/style.css';

API JavaScript

Chaque instrument Panel s'instancie via un sélecteur et se pilote par code, notamment avec la méthode set(). Les composants se synchronisent entre eux et acceptent des données temps réel issues de WebSocket, SSE ou de toute autre source applicative.

// Poste de vol : instancier par sélecteur, piloter par API
const cockpit = new SXP.Panel.Cockpit("#cockpit");
cockpit.set({ pitch: 12, roll: -18, heading: 270, alt: 0.3, speed: 0.6 });

// Cadran à aiguille avec zones (l'aiguille vibre en butée rouge)
const bar = new SXP.Panel.Gauge("#pressure", {
  min: 0, max: 10, unit: "bar",
  zones: [{ from: 0, to: 7, color: "#33ff66" }, { from: 9, to: 10, color: "#ff3355" }]
});
bar.set(8.4);

// Synchroniser deux composants : un potentiomètre pilote l'oscilloscope
const scope = new SXP.Panel.Scope("#scope", { wave: "sine", freq: 3 });
const knob  = new SXP.Panel.Knob("#freq", { min: 1, max: 12, val: 3 });
knob.on(v => scope.set({ freq: v }));

// Alimenter un radar depuis n'importe quelle source temps réel
const radar = new SXP.Panel.Radar("#radar", { range: 0.7 });
socket.onmessage = e => radar.set(JSON.parse(e.data));

Instruments Canvas

Gauge, Scope, Radar, Vumeter, Geiger, Thermometer, Compass, Recorder, Rollcounter, Rotameter, Punchtape, Waterfall — .set(valeur) ou .set({…}), animés en temps réel, en pause hors écran.

Poste de vol

Cockpit, Stick — cockpit.set({pitch, roll, heading, vario, alt, speed}), stick.onInput(fn).

Contrôles pilotés

Knob, Selector, Equalizer — .set(), .on(fn), .feed(spectre).

Référence des instruments

Chaque instrument s'initialise seul depuis le HTML (attributs data-*) ou par code (new SXP.Panel.Xxx(sélecteur, options)). Les options ci-dessous valent pour les deux : en HTML, value s'écrit data-val, majorTicks devient data-majors, minorTicks data-minors, zones se note "950,990,#ffb000;990,1020,#5a6b7c". Toutes les méthodes renvoient l'instance (chaînables) ; un sélecteur absent rend une instance muette, jamais une erreur.

ClasseHTMLOptions (défaut)Méthodes
Gauge
cadran à aiguille
<canvas class="sxp-inst" data-inst="barometer|manometer|voltmeter"> min (0), max (100), value, unit, label, accent (#ff6600), decimals (0), majorTicks (5), minorTicks (4), zones [{from, to, color}], startDeg (−135), endDeg (135), digital (true) set(v), config({…}), value(). L'aiguille vibre dans une zone rouge.
Scope
oscilloscope
data-inst="oscilloscope" wave sine|square|triangle|saw|noise (sine), freq (2), amp 0..1 (0.7), sweep 0..1 (0.5), intensity 0..1 (0.8), focus 0..1 (0.7), disp line|dots (line), color (#33ff66), power (true) set({…}) — toute option est modifiable à chaud, start(), stop()
Radar
radar 1940
data-inst="radar" speed rad/frame (0.028), gain 0..1 (0.7), persist 0..1 (0.6), range 0..1 (0.7), color set({…}), start(), stop()
Vumeterdata-inst="vumeter"value 0..1 (0)set(v) — balistique : attaque vive, chute lente
Geigerdata-inst="geiger"value µSv/h (0.15), max (30)set(µSv/h) — crépitement sonore et boîtier qui tremble au-delà du seuil
Thermometerdata-inst="thermometer"min (−40), max (50), unit (°C), value (20)set(v), value()
Compass
boussole de marine
data-inst="compass"value degrés (0)set(deg) ; set("spin") affole l'aiguille, set("normal") la calme
Recorder
sismographe
data-inst="recorder"—feed(0..1) niveau imposé, quake(0..1) secousse à la demande
Rollcounter
odomètre
data-inst="rollcounter"digits (6), value (0), rate unités/s (0 = figé)set(v), config({rate, digits}), value()
Rotameterdata-inst="rotameter"max (120), unit, value (0)set(v)
Punchtape
bande perforée
data-inst="punchtape"text, speed (1), colorset(texte) perfore un nouveau message, value(), start() / stop()
Waterfall
cascade spectrale ASCII
data-inst="waterfall"cols (32), carrier 0..1 (0.5), gain 0..1 (0.8), colorfeed([0..1, …]) pousse une ligne de spectre ; sans données, porteuse synthétique — set(carrier) la déplace
Cockpit
poste de vol
<div class="sxp-cockpit" data-dials="horizon,vario,cap,alt,vitesse" data-size="82"> dials liste ordonnée des cadrans, size px (82) set({pitch °, roll °, heading °, vario −1..1, alt 0..1, speed 0..1}) — chaque clé est optionnelle, les aiguilles s'amortissent
Stick
manche + gaz
<div class="sxp-stick" data-label data-stick data-throttle> label, stickLabel, throttleLabel onInput(fn), x(), y() −1..1, throttle() 0..1
Knob
potentiomètre
<div class="sxp-knob" data-min data-max data-step data-val> min (0), max (100), step (1), val on(fn) à chaque geste (souris, molette, clavier), set(v) déplace l'aiguille sans émettre, value()
Selector
commutateur cranté
<div class="sxp-selector" data-arc="150"> + enfants [data-val] arc amplitude en degrés (80 × (n − 1), max 300) on(fn(valeur, index)), set(valeur), value()
Equalizer
analyseur à LED
<div class="sxp-eq" data-bands="32" data-auto="false"> bands (32), auto simulation au chargement (true) feed([0..1 × bands]) spectre externe (FFT Web Audio…), on(fn({levels, level, beat})) à chaque frame, start(), stop()

Boutons

Des boutons d'action lumineux, lisibles et déclinables, pensés pour afficher clairement les états et les variantes d'une interface.

Variantes
Tailles
Segments (accent ambre)
<button class="sxp-btn is-on">Actif</button>

Interrupteurs on/off

Des toggles animés à LED pour rendre les activations, désactivations et changements d'état immédiatement compréhensibles. Chaque passage à ON déclenche une brève rampe d'allumage.

Pastille LED
Glissant
Rocker
Poussoir lumineux
<label class="sxp-toggle">
  <input type="checkbox" checked><span class="sxp-led-dot"></span> Reverb
</label>

Curseurs, faders & indicateurs

Sliders horizontaux, faders verticaux et voyants LED. Le banc de faders, le vumètre et le voyant d'activité sont pilotés en direct par le spectre de notre simulation musicale.

Curseurs
Gain
Ton
Voyants
Repos Actif Occupé Erreur
Banc de faders
63
250
1k
4k
16k
Égaliseur 32 bandes — audio réel (boucle 4 s générée localement)

Potentiomètres

Des knobs rotatifs qui donnent aux réglages fins une présence visuelle inspirée des équipements audio et industriels. Glissez verticalement, à la molette ou au clavier.

Drive
Mix
Cutoff
<div class="sxp-knob" data-min="0" data-max="100" data-val="35"></div>

Radar 1940

Un écran radar PPI d'époque : balayage tournant à rémanence phosphore, échos qui s'illuminent au passage du faisceau puis s'estompent lentement. Les potentiomètres pilotent le balayage, le gain, la portée et la rémanence.

Balayage
Gain
Portée
Rémanence

Appareils de mesure

Des instruments vintage réellement fonctionnels : cadrans à aiguille dessinés sur canvas, pilotables par API (set(valeur)) et ici directement par les contrôles ci-dessus. Le voltmètre embarque un sélecteur de mode (V / A / Ω). Les assemblages refmanche et refcockpit composent un poste de vol complet.

Baromètre
Régler
Manomètre
Voltmètre
Mesure
Oscilloscope
Mode d'affichage
Réglages
Fréq.
Balayage
Ampl.
Intensité
Netteté
// API : chaque cadran expose canvas._sxp.set(valeur)
<canvas class="sxp-inst" data-inst="manometer" data-min="0" data-max="10"
        data-zones="0,7,#33ff66;7,9,#ffb000;9,10,#ff3355"></canvas>

Poste de vol — refmanche + refcockpit

Le manche à balai (ressort de rappel au centre) et la manette des gaz (à friction) pilotent en direct le cluster d'instruments de vol : assiette, inclinaison, cap, variomètre, altitude et vitesse. Tout est dessiné sur canvas et pilotable par API.

// le manche pilote le cockpit
stick._sxp.onInput(function (s) {
  cockpit._sxp.set({ pitch: s.y * 60, roll: s.x * 45, heading: cap, speed: s.throttle });
});

Instruments Canvas en mouvement

Panel étend sa collection avec des instruments de mesure vintage bien au-delà des cadrans ronds : VU-mètre, enregistreur à bande, odomètre, rotamètre, thermomètre, boussole et compteur Geiger — et deux appareils au thème terminal : une bande perforée de téléscripteur qui décode son message au défilé, et la cascade spectrale ASCII d'un récepteur radio. Chaque appareil est dessiné sur Canvas, pilotable en JavaScript via set(), animé en temps réel et fonctionne sans aucune dépendance.

↻ Glissez pour orienter le globe
Globe · position ciblée
VU-mètre
Enregistreur à bande
Compteur à rouleaux
Rotamètre
Thermomètre
Boussole
Compteur Geiger
Bande perforée · terminal
♪ suit l'égaliseur quand « Lecture » est coché Cascade spectrale ASCII · terminal
// chaque instrument s'instancie par sélecteur et se pilote par API
const vu = new SXP.Panel.Vumeter("#vu");
vu.set(0.82);                 // niveau audio 0..1 (ballistique VU)

const compas = new SXP.Panel.Compass("#compas");
compas.set(270);                // cap en degrés

const trace = new SXP.Panel.Recorder("#trace");
socket.onmessage = e => trace.feed(JSON.parse(e.data).v);

const bande = new SXP.Panel.Punchtape("#bande");
bande.set("BUILD 1.1.0 OK");     // perfore un nouveau message

const sdr = new SXP.Panel.Waterfall("#sdr");
sdr.feed(spectre);              // une ligne : tableau de niveaux 0..1

Thème terminal

Un conteneur .sxp-terminal transforme n'importe quel bloc HTML en écran phosphore vert : titres, liens, tableaux et champs natifs sont habillés d'office, et des composants à la Bootstrap — boutons, badges, alertes, barre de progression, carte, invite — s'écrivent avec le préfixe .sxp-t-. Variante ambre : .sxp-terminal--amber.

SYNAPX OS v5.1 — console

synapx@panel:~$ status --all

Boutons

Badges & alertes

Service en ligne · file 12 · disque 81 % · sonde perdue · build #4817

Info — synchronisation terminée en 0,42 s.
Attention — la température du bloc 3 dépasse 60 °C.
Erreur — liaison radar interrompue, reprise automatique dans 30 s.

Progression

Tableau

CapteurZoneValeurÉtat
PressionBloc 11 013 hPaok
TempératureBloc 361,4 °Chaut
DébitCircuit A42 L/minok
RadiationsExtérieur0,15 µSv/hnominal

Formulaire

Carte & citation

Nœud bm-dev-01

Charge 0,42 · 18 canvas actifs · 0 rAF hors écran.

Voir l'API →

dernière mise à jour il y a 4 s
« Un instrument qui ne mesure rien n'est qu'une décoration. »
$ npm install @synapxlab/panel
added 1 package in 0.8s

Accordéon & volet à onglets

  • 00:12:04 — sonde radar recalibrée
  • 00:12:31 — bloc 3 : température 61,4 °C
  • 00:13:02 — synchronisation OK (0,42 s)

Replié par défaut : un clic sur l'en-tête le déplie.

Pression, température, débit et radiations : quatre capteurs nominaux. L'onglet actif replie le volet ; un autre onglet bascule la face.

Navigation

  • Pression ok
  • Température haut
  • Débit ok
  • Radiations nominal

synapx@panel:~$ theme --amber

ambre
<!-- tout bloc HTML devient un écran phosphore ; variante : sxp-terminal--amber -->
<div class="sxp sxp-terminal">
  <h2>Diagnostic</h2>
  <button class="sxp-t-btn sxp-t-btn--primary">Valider</button>
  <span class="sxp-t-badge sxp-t-badge--warn">81 %</span>
  <div class="sxp-t-alert sxp-t-alert--danger"><strong>Erreur</strong> — liaison perdue</div>
  <div class="sxp-t-progress" data-label="62 %"><i style="width:62%"></i></div>
  <table>…</table>  <input type="text">  <a href="#">lien</a>
</div>