ttfx: Terminalteksteffecten als een enkel statisch binair bestand

ls -la | ttfx decrypt
cat banner.txt | ttfx beams
fortune | ttfx --random-effect
git log --oneline -10 | ttfx matrix

Erkenningen

Dit project is een port van TerminalTextEffects (TTE), ontwikkeld door ChrisBuilds. Elk effect, de animatie-engine en de command-line interface zijn hun ontwerp; dit project vertaalt dat werk naar Rust en voegt niets eigen toe aan de artistieke vormgeving. Als je het resultaat waardeert, wordt aangeraden om het origineel een ster te geven.

TTE is gelicenseerd onder MIT en deze port is dat ook; het oorspronkelijke copyright is behouden in de LICENSE en NOTICE bestanden. Ideeën voor nieuwe effecten dienen upstream te worden ingediend.

Waarom een port?

TTE is een Python-pakket. Dat is de juiste keuze voor een bibliotheek, maar voor een shell-tool die in je prompt-pipeline leeft, betekent dit dat er een interpreter nodig is, er een installatiestap aan voorafgaat en er ongeveer 65 ms importtijd verstrijkt voordat het eerste frame verschijnt. ttfx is één binair bestand zonder afhankelijkheden dat start in een halve milliseconde.

Dit verschil is de reden waarom dit project bestaat. Op een canvas op volledig scherm raken zwaardere effecten onder Python tekort aan rekenkracht. Hieronder volgt de tijd die nodig is om een volledige animatie te renderen (met pacing uitgeschakeld, zodat doorvoersnelheid wordt gemeten in plaats van sleep()):

Bij 200×50 cellen

EffectFramesttfx tijdPython TTE tijdttfx fps
slide37576 ms2.203 ms4.930
beams732181 ms5.564 ms4.050
rings1.566521 ms10.439 ms3.004
waves633374 ms8.745 ms1.693
startup0,5 ms64 ms

Over de 35 effecten die niet worden beperkt door de kloktijd (wall-clock time), is de mediane versnelling 27,5× (bereik 17,1×–47,4×). De twee effecten die dat wel zijn — matrix en thunderstorm — besteden het grootste deel van hun runtime aan een vaste animatieduur die door geen enkele implementatie kan worden verkort; deze scoren respectievelijk 1,9× en 1,3×. Wat ttfx hier biedt, is een veel hogere framerate binnen dat tijdsbestek, niet een kortere duur.

Dit kan worden gereproduceerd met python3 tools/tests/benchfull.py, of door TTFXBENCHCOLS, TTFXBENCHLINES en TTFXBENCH_FILL=1 in te stellen voor de bovengenoemde fullscreen-cijfers. Beide zijden voeren hun echte user-facing commando uit, beste van vijf.

De effecten

Er zijn 37 effecten, die elk het Omarchy-logo animeren. Elk frame uit de Rust-binary is byte-identiek aan wat het Python-origineel produceert met dezelfde input en seed.

  • beams: Creëert stralen die over het canvas bewegen en de tekens erachter verlichten.
  • binarypath: Binaire representaties van elk teken bewegen naar de home-coördinaat van het teken.
  • blackhole: Tekens worden opgeslokt door een zwart gat en exploderen naar buiten.
  • bouncyballs: Tekens zijn stuiterballen die van bovenaf op het canvas vallen.
  • bubbles: Tekens vormen bellen die naar beneden zweven en knappen.
  • burn: Brandt verticaal in het canvas.
  • colorshift: Toont een gradiënt waarbij kleuren over de terminal verschuiven.
  • crumble: Tekens verliezen kleur, verbrokkelen tot stof, worden opgezogen en opnieuw gevormd.
  • decrypt: Toont een decryptie-effect in filmstijl.
  • errorcorrect: Sommige tekens beginnen op de verkeerde positie en worden opeenvolgend gecorrigeerd.
  • expand: Breidt de tekst uit vanuit één enkel punt.
  • fireworks: Tekens lanceren en exploderen als vuurwerk voordat ze op hun plek vallen.
  • highlight: Laat een speculaire highlight over de tekst lopen.
  • laseretch: Een laser etst tekens op de terminal.
  • matrix: Het digitale regen-effect uit The Matrix.
  • middleout: Tekst breidt uit in één rij of kolom in het midden van het canvas en verspreidt zich daarna.
  • orbittingvolley: Vier launchers cirkelen rond het canvas en vuren salvo's tekens naar binnen om de inputtekst vanuit het centrum op te bouwen.
  • overflow: Inputtekst loopt over en scrolt door de terminal in een willekeurige volgorde totdat deze uiteindelijk geordend verschijnt.
  • pour: Giet de tekens vanuit de opgegeven richting in positie.
  • print: Regels worden één voor één geprint, volgend op een printhoud. De printhoud voert line feed en carriage return uit.
  • rain: Laat tekens regenen vanaf de bovenkant van het canvas.
  • randomsequence: Print de inputdata in een willekeurige volgorde.
  • rings: Tekens worden verspreid en vormen draaiende ringen.
  • scattered: Tekst is verspreid over het canvas en beweegt naar de juiste positie.
  • slice: Snijdt de input doormidden en schuift deze vanuit tegenovergestelde richtingen op zijn plek.
  • slide: Schuift tekens in beeld vanuit buiten de terminal.
  • smoke: Rook vult het canvas en kleurt alle tekens die het kruist.
  • spotlights: Spotlights doorzoeken het tekstgebied, verlichten tekens, komen samen in het centrum en breiden zich daarna uit.
  • spray: Tekent de tekens die met variërende snelheden ontstaan vanuit één enkel punt.
  • swarm: Tekens worden gegroepeerd in zwermen en bewegen over de terminal voordat ze op hun plek landen.
  • sweep: Veegt over het canvas om ongekleurde tekst te onthullen; een omgekeerde veeg kleurt de tekst in.
  • synthgrid: Creëert een raster dat wordt gevuld met tekens die oplossen in de uiteindelijke tekst.
  • thunderstorm: Creëert een onweersbui in de terminal.
  • unstable: Genereert tekens in een rommelige volgorde, laat ze exploderen naar de rand van het canvas en voegt ze daarna samen in de juiste lay-out.
  • vhstape: Regels tekens glitchen naar links en rechts en verliezen detail, zoals bij een oude VHS-band.
  • waves: Golven bewegen over de terminal en laten de tekens achter.
  • wipe: Veegt de tekst over de terminal om tekens te onthullen.

Elk effect heeft zijn eigen opties; gebruik ttfx <effect> --help. Enkele van de voorbeelden maken gebruik van verkorte tijdsfasen om de loop observeerbaar te houden (matrix --rain-time 3, thunderstorm --storm-time 3, vhstape --total-glitch-time 250, spotlights --search-duration 80, errorcorrect --error-pairs 0.5); alle overige instellingen zijn standaard.

Getrouwheid (Fidelity)

Dit is een pariteitsport, geen "reimplementatie in geest". Bij dezelfde input, configuratie en willekeurige trekkingen produceert ttfx byte-identieke frames als het Python-origineel. Dit is mechanisch geverifieerd in CI tegen een vastgepinde upstream checkout (v0.15.0), niet op basis van visuele inspectie.

Testsuite

ChecksWat het bewijst
tools/parity/run_suite.sh (354)De framestroom van elk effect, byte voor byte, over configuraties en seeds.
tools/parity/tty_compare.sh (41)De volledige terminal byte-stream — canvasvoorbereiding, cursorbewegingen, teardown.
tools/tests/cli_corpus.sh (19)Exit-codes en stdout/stderr routing.
cargo testGoldens + traces: easing/geometry/gradient waarden en engine state machines.

Om dit mogelijk te maken, zijn de eigenaardigheden van upstream bewust gereproduceerd in plaats van "gecorrigeerd": Python's banker's rounding, gradiënten gebouwd op basis van integer-vloerdeling in plaats van float-interpolatie, een bezier booglengte-benadering die het laatste segment weglaat, en loop-scènes die zichzelf bij elke tick als voltooid rapporteren. Deze zijn gecatalogiseerd in plan.md; de plaatsen waar Python's ongeordende iteratie moest worden vastgelegd staan in docs/ordering-inventory.md.

Er zijn twee bewuste verschillen:

  1. De generatie van willekeurige getallen is niet bit-compatibel met CPython — ttfx gebruikt xoshiro256++, dus --seed is reproduceerbaar binnen ttfx, maar komt niet overeen met de Mersenne Twister van Python. (De pariteitsharness wisselt een gedeelde PRNG in beide zijden, wat framevergelijking mogelijk maakt).
  2. Python-plugin effecten worden niet ondersteund, aangezien er geen interpreter is om deze te laden.

Gebruik

Het basisgebruik volgt dit patroon: <producer> | ttfx [terminal opties] <effect> [effect opties]

  • ttfx --help : Toont alle 37 effecten en de terminal-opties.
  • ttfx <effect> --help : Toont de opties voor één specifiek effect.
  • ttfx --random-effect : Kiest een willekeurig effect (--include-effects / --exclude-effects om te filteren).
  • ttfx --print-completion bash|zsh : Genereert autocomplete-scripts.

Terminal-opties (canvasgrootte, anchoring, kleurafhandeling, framerate, tekstwrapping) komen vóór de effectnaam; effect-opties komen erna. De optienaam en standaardwaarden komen overeen met tte, zodat bestaande aanroepen werken door enkel de naam van het binary te vervangen.

Bouwen

cargo build --release
cargo build --release --target x86_64-unknown-linux-musl   # statisch, ~3,3 MB

Voor het draaien van de pariteitssuites zijn python3 en een kopie van upstream nodig:

./tools/parity/fetch_reference.sh   # Cloont TTE op de gepinde commit
./tools/parity/run_suite.sh

Upstream is hier niet als vendor opgenomen — de harness haalt het op, omdat het hun code is.

Scope en Compatibiliteit

Ondersteund op Linux en macOS. Oorspronkelijk gebouwd voor Omarchy; er is geen target voor een specifieke libc, en CI draait de tests en CLI corpus op beide platforms. De byte-exacte pariteitsuites blijven gepind aan Linux/glibc — Apple's libm rondt een paar transcendentale functies net anders af (last-ulp), wat in echte frames door kwantisering wordt verborgen, maar bij een bit-exacte vergelijking naar voren zou komen.

Licentie

MIT — zie het LICENSE bestand, dat zowel het copyright van dit project als het originele TerminalTextEffects copyright bevat, en het NOTICE bestand voor de volledige attributie.