FlipArt - universelles Klapp-Display

Uhr (HH:II:SS)
Datum + Uhr (YYYY-MM-DD HH:II:SS, terminal)
Countdown bis Silvester (DD HH II SS, neon)
Countup seit 01.01.2024 (YYYY MM DD HH II SS, mono)
Countup mit [DD] = dynamisch (paper)
Timer 10 Min (II:SS, neon)
Text auto-cycle (paper) - klick = pause
Text auto-cycle MIT scramble (terminal) - klick = pause

FlipArt ist ein universelles Klapp-Display für Uhrzeiten, Countdowns, Timer und Text. Konfiguration erfolgt entweder vollständig deklarativ über data-*-Attribute oder programmatisch über JavaScript. Auto-Init beim DOM-ready inklusive.

flipclock.js JavaScript flipclock.css Theme-Tokens

Shadow-DOM-Kapselung

Ab jetzt rendert FlipArt in einen Shadow Root pro Instanz. Das gesamte Painting liegt gekapselt im Widget - CSS der einbettenden Seite kann die interne Darstellung nicht mehr überschreiben. Rohe Tag- oder Nachfahren-Selektoren wie .panel div oder section * greifen nicht mehr durch (kein dunkel-auf-dunkel, keine Fremd-Borders).

flipclock.css enthält jetzt ausschließlich Theme-Tokens (CSS Custom Properties). Diese werden am .flipart-Host gesetzt, vererben über die Shadow-Grenze und bleiben von außen überschreibbar. Theming läuft daher weiterhin komplett über data-flip-theme und die --fa-*-Variablen - nur eben nicht mehr über CSS auf die internen .fa-*-Klassen.

Quick Start

CSS und JS einbinden, ein Element mit Klasse .flipart anlegen - fertig.

<link rel="stylesheet" href="flipclock.css">
<script src="flipclock.js" defer></script>

<div class="flipart"
     data-flip-mode="clock"
     data-flip-format="HH:II:SS"></div>

Token-Format

Das Format-String beschreibt, welche Zeit-Einheiten angezeigt werden und welche Trennzeichen dazwischen stehen. Tokens werden 1:1 ausgetauscht, alles andere bleibt als Literal stehen.

TokenBedeutungDefault-Stellen
YYYYJahre4
MMMonate (1–12 im Clock-Mode)2
DDTage2
HHStunden2
IIMinuten (analog zu PHP date('i'))2
SSSekunden2

Brackets - dynamische Stellen

Ein Token in eckigen Klammern (z.B. [DD]) startet mit der Default-Stellenzahl, wächst aber nach links wenn der Wert mehr Ziffern braucht. Sinnvoll nur für das erste Token, da nur dieses die übergeordneten Zeit-Anteile aufaddiert bekommt und damit überlaufen kann.

"DD HH II SS"     → bei 5000 Tagen wird zu "00" truncated (max 99 Tage)
"[DD] HH II SS"   → wächst auf "5000" Tage
"YYYY-MM-DD"      → ISO-Datum
"DD.MM.YYYY HH:II:SS" → klassisches DE-Format mit Uhr

Modi

ModusBeschreibungPflicht-Attribute
clock Aktuelle Uhrzeit. Alle Tokens im Format werden auf die jeweilige Komponente von new Date() gemappt. -
countdown Runter zu einem Zieldatum. data-flip-target
countup Hoch ab einem Startdatum. data-flip-target
timer Reiner Sekunden-Countdown ab Aufruf. data-flip-duration
text Statischer oder zyklisch wechselnder Text. data-flip-text oder data-flip-cycle-texts

Splitting-Logik

Bei countdown und countup entscheidet das erste Token im Format, wie die Differenz aufgeteilt wird:

Das erste Token bekommt zudem alle übergeordneten Anteile aufaddiert - bei "HH II SS" akkumulieren z.B. ganze Tage in der Stundenzahl.

Scramble-Effekt (text-Modus)

Beim Wechsel zwischen Texten klappert jedes Tile durch alle Zwischen-Zeichen seines Sets - wie eine alte Flughafen-Anzeigetafel. Beispiel: U auf R wechseln läuft U → V → W → X → Y → Z → A → B → … → Q → R (forward, mit Wrap durchs Alphabet).

Drei Zeichen-Sets sind hardcoded: A–Z, a–z, 0–9. Jedes Tile scrambelt nur innerhalb des Sets, in dem sein Zielzeichen liegt. Cross-Set-Wechsel (z.B. O! oder ' 'A) werden als einzelner direkter Flip behandelt.

Aktivierung

<div class="flipart"
     data-flip-mode="text"
     data-flip-text="ARRIVAL"
     data-flip-cycle="3500"
     data-flip-cycle-texts='["ARRIVAL","BOARDING","ENROUTE ","DEPARTED"]'
     data-flip-scramble="true"
     data-flip-scramble-step="55"></div>

Timing

Während des Scramble läuft jedes Tile mit der durch data-flip-scramble-step vorgegebenen Schritt-Dauer (Default 60 ms). Damit die einzelnen Klapp-Animationen rechtzeitig durchrendern, setzt die Bibliothek dafür temporär --fa-flip-duration als inline-style auf jedes Tile.

Der letzte Schritt jedes Tiles bekommt die volle Animations-Dauer zurück - das Zielzeichen klappt damit als sichtbarer Abschluss langsamer ein. Tiles mit kürzerem Pfad sind früher fertig, Tiles mit langem Pfad scramblen weiter.

CSS-Voraussetzung: Damit das Step-Tempo greift, muss deine flipclock.css die Animation über --fa-flip-duration parametrisieren - z.B.:
animation: flip-down var(--fa-flip-duration, 0.6s) ease-in-out forwards;
Falls die Variable im CSS nicht referenziert wird, läuft jeder Scramble-Schritt mit der unveränderten Standard-Animations-Dauer - der Effekt wirkt dann weniger crisp, aber die Bibliothek bricht nichts.

Cycle-Intervall sinnvoll wählen

data-flip-cycle sollte länger sein als die maximale Scramble-Dauer plus etwas Lese-Zeit. Worst-Case: 25 Schritte × 60 ms = 1.5 s, plus volle finale Animation (~600 ms) → mind. ~2 s + Lese-Zeit. Bei zu kurzem Cycle wird der laufende Scramble einfach abgebrochen und der nächste startet - funktional ok, optisch unruhig.

Sanftes Pausieren mit pause()

Beim Pausieren mitten in einem Scramble wäre es störend, wenn die Tiles in einem zufälligen Zwischen-Zustand stehen bleiben (BOARDING → DRMITLL). Daher: pause() bricht den Cycle sofort ab, lässt aber den aktuellen Scramble bis zum Zieltext durchlaufen. Erst danach ist die Instanz angehalten. Wer hartes Stop will, ruft stop(). Außerhalb von Scramble-Übergängen ist pause() identisch zu stop().

// Toggle-Button für Demo-Element:
el.addEventListener('click', () => {
  const fa = el._flipArt;
  fa.isRunning ? fa.pause() : fa.start();
});

Richtungen

WertVerhalten
forward (default)Vorwärts durchs Set, mit Wrap am Ende. U → R = 23 Schritte.
backwardRückwärts. U → R = 3 Schritte.
shortestWählt automatisch die kürzere der beiden Richtungen.

Data-Attribute

AttributWertBeschreibung
data-flip-modeclock | countdown | countup | timer | textBetriebsmodus. Default: clock.
data-flip-formatz.B. HH:II:SSToken-Format. Default je nach Modus.
data-flip-targetISO-DatumsstringZiel- bzw. Startdatum für countdown/countup.
data-flip-durationZahl (Sekunden)Dauer für timer-Modus.
data-flip-textStringInitialer Text im text-Modus.
data-flip-cycle-textsJSON-Array oder pipe-separiertTexte zum Durchwechseln, z.B. ["A","B","C"] oder A|B|C.
data-flip-cycleZahl (ms)Intervall des Text-Cycles.
data-flip-scrambletrue | falseAktiviert Scramble-Effekt im text-Modus. Default false.
data-flip-scramble-stepZahl (ms)Tempo der Zwischen-Klappschritte. Default 60.
data-flip-scramble-directionforward | backward | shortestKlapp-Richtung. Default forward.
data-flip-labelsde | en | offSprache der Einheiten-Labels oder ausschalten.
data-flip-thememono | paper | neon | terminalVorgefertigtes Theme. Default ist Stahl-Dunkel/Bernstein.
data-flip-autostartfalseVerhindert automatischen Start beim Init.

JavaScript-API

Programmatische Initialisierung und Steuerung:

const fa = new FlipArt(element, {
  mode: 'countdown',
  target: '2026-12-31T23:59:59',
  format: '[DD] HH II SS',
  labels: 'de',
  onComplete: (instance) => console.log('done', instance)
});

// Text-Modus mit Scramble:
const ft = new FlipArt(textEl, {
  mode: 'text',
  texts: ['ARRIVAL','BOARDING','ENROUTE ','DEPARTED'],
  cycle: 3500,
  scramble: true,
  scrambleStep: 55,
  scrambleDirection: 'forward'
});

fa.start();              // startet (oder neu-startet)
fa.stop();               // stoppt alle Timer
fa.update('2027-01-01'); // ändert target / duration / text
fa.destroy();            // entfernt DOM & Bindings

// Alle .flipart-Elemente nachträglich initialisieren (idempotent):
FlipArt.init();

// Optional: jQuery-Bridge
$('.flipart').flipart({ mode: 'clock' });

Methoden

MethodeBeschreibung
start()Startet den Tick-Loop. Bei clock sekunden-synchronisiert.
stop()Hartes Stop: bricht alle Timer und einen laufenden Scramble sofort ab.
pause()Sanftes Stop: bricht den Cycle ab, lässt aber einen laufenden Scramble bis zum Zieltext durchlaufen. Ohne aktiven Scramble identisch zu stop().
update(value)Ändert je nach Modus target, duration oder text und re-rendert.
destroy()Räumt vollständig auf: stoppt Timer, leert Inhalt, löst _flipArt-Backref.
isRunning (Getter)Truthy, wenn ein Tick, Cycle oder austrudelnder Scramble aktiv ist. Für Toggle-Buttons.
FlipArt.init(selector?)Statisch. Initialisiert alle passenden Elemente. Idempotent.

Themes

Vier vorgefertigte Themes via data-flip-theme. Plus ein Default-Look ohne Attribut (dunkles Stahl mit bernstein-farbiger Glyph).

Eigene Themes per CSS-Variablen

Alle Farben und Maße sind über CSS Custom Properties steuerbar:

.flipart.mein-theme {
  --fa-bg-top:    linear-gradient(180deg, #444 0%, #222 100%);
  --fa-bg-bottom: linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%);
  --fa-color:     #ff5500;
  --fa-divider:   rgba(0, 0, 0, 0.7);
  --fa-radius:    0.15em;
  --fa-tile-w:    0.9em;
  --fa-tile-h:    1.3em;
  --fa-tile-gap:  0.08em;
  --fa-group-gap: 0.6em;
}

Skalierung erfolgt über font-size auf dem .flipart-Container - alle internen Maße sind in em definiert. Die Bibliothek snappt die Werte zur Laufzeit auf das Device-Pixel-Raster, um Subpixel-Artefakte beim Klappen zu vermeiden.

Da das Painting gekapselt ist, ist das der einzige Weg zum Theming: CSS auf die internen .fa-*-Klassen wirkt nicht mehr. Eigene Themes also immer als --fa-*-Overrides auf .flipart bzw. .flipart[data-flip-theme="…"] schreiben.

Hinweise