tachyonfx

Crates.iotachyonfx
lib.rstachyonfx
version0.18.0
created_at2024-06-20 15:30:01.64187+00
updated_at2025-09-07 12:24:03.307844+00
descriptionA ratatui library for creating shader-like effects in TUIs.
homepagehttps://github.com/junkdog/tachyonfx
repositoryhttps://github.com/junkdog/tachyonfx
max_upload_size
id1278080
size1,000,202
Adrian Papari (junkdog)

documentation

https://docs.rs/tachyonfx

README

tachyonfx

Crates.io Documentation License Downloads Deps.rs

A ratatui library for creating shader-like effects in terminal UIs. Build complex animations by composing and layering simple effects, bringing smooth transitions and visual polish to the terminal.

demo

➡️ Try exabind - experience tachyonfx in your browser without installing anything!

✨ Features

  • 30+ unique effects — color transformations, text animations, geometric distortions, plus support for custom effects
  • Effect composition — chain and combine effects for sophisticated animations
  • Interactive browser editor — design and preview effects in real-time with TachyonFX FTL
  • Runtime effect compilation — create effects from strings using the built-in DSL
  • Cell-precise targeting — apply effects to specific regions or cells matching custom criteria

🚀 Quick Start

Add tachyonfx to your Cargo.toml:

cargo add tachyonfx

Create your first effect:

use std::{io, time::Instant};

use ratatui::{crossterm::event, prelude::*, widgets::Paragraph};
use tachyonfx::{fx, EffectManager, Interpolation};

fn main() -> io::Result<()> {
    let mut terminal = ratatui::init();
    let mut effects: EffectManager<()> = EffectManager::default();

    // Add a simple fade-in effect
    let fx = fx::fade_to(Color::Cyan, Color::Gray, (1_000, Interpolation::SineIn));
    effects.add_effect(fx);

    let mut last_frame = Instant::now();
    loop {
        let elapsed = last_frame.elapsed();
        last_frame = Instant::now();

        terminal.draw(|frame| {
            let screen_area = frame.area();

            // Render your content
            let text = Paragraph::new("Hello, TachyonFX!").alignment(Alignment::Center);
            frame.render_widget(text, screen_area);

            // Apply effects
            effects.process_effects(elapsed.into(), frame.buffer_mut(), screen_area);
        })?;

        // Exit on any key press
        if event::poll(std::time::Duration::from_millis(16))? {
            if let event::Event::Key(_) = event::read()? {
                break;
            }
        }
    }

    ratatui::restore();
    Ok(())
}

📸 Examples

Explore the examples to see effects in action:

# Basic effects showcase
cargo run -p basic-effects

# Effect timeline visualization
cargo run -p fx-chart

# Minimal setup example
cargo run -p minimal

# Interactive effect registry demo
cargo run -p effect-registry

# Complete effect showcase
cargo run -p effect-showcase

# Tweening examples
cargo run -p tweens

🎯 Getting Started

Try it in your browser

TachyonFX FTL is a browser-based editor for creating and tweaking effects in real-time.

Basic Concepts

  1. Effects are stateful — Create once, apply every frame
  2. Effects transform rendered content — Apply after widgets render
  3. Effects compose — Build complex animations from simple pieces

Simple Example: Fade In

use tachyonfx::{fx, Effect, CellFilter};

// Create a fade-in effect
let mut fade = fx::fade_from(Color::Black, Color::White, 
    EffectTimer::from_ms(500, QuadOut));

// Apply to red text only
fade.set_cell_filter(CellFilter::FgColor(Color::Red));

// In your render loop
fade.process(delta_time, buf, area);

Combining Effects

// Run multiple effects in parallel
let effects = fx::parallel(&[
    fx::fade_from_fg(Color::Red, 500),
    fx::slide_in(Direction::LeftToRight, 800),
]);

// Or sequence them
let effects = fx::sequence(&[
    fx::fade_from_fg(Color::Black, 300),
    fx::coalesce(500),
]);

Using the DSL

Create effects from strings at runtime:

use tachyonfx::dsl::EffectDsl;

let effect = EffectDsl::new()
    .compiler()
    .compile("fx::dissolve(500)")
    .expect("valid effect");

📦 Effect Reference

Color Effects

Transform colors over time for smooth transitions.

  • fade_from / fade_to — Transition colors
  • fade_from_fg / fade_to_fg — Foreground color transitions
  • hsl_shift — Animate through HSL color space
  • term256_colors — Downsample to 256-color mode

Text & Motion Effects

Animate text and cell positions for dynamic content.

  • coalesce / dissolve — Text materialization effects
  • slide_in / slide_out — Directional sliding animations
  • sweep_in / sweep_out — Color sweep transitions
  • explode — Particle dispersion effect

Control Effects

Fine-tune timing and behavior.

  • parallel — Run multiple effects simultaneously
  • sequence — Chain effects one after another
  • repeat — Loop effects with optional limits
  • ping_pong — Play forward then reverse
  • with_duration — Override effect duration

Geometry Effects

Transform positions and layout.

  • translate — Move content by offset
  • resize_area — Scale effect bounds
  • translate_buf — Copy and move buffer content

🔧 Advanced Features

Cell Filtering

Apply effects selectively:

// Only apply to cells with specific colors
fx::dissolve(500)
    .with_filter(CellFilter::FgColor(Color::Red))

// Target specific regions
let filter = CellFilter::AllOf(vec![
    CellFilter::Outer(Margin::new(1, 1)),
    CellFilter::Text,
]);

Custom Effects

Create your own effects:

fx::effect_fn(state, timer, |state, context, cell_iter| {
    // Your custom effect logic
    timer.progress()
})

Alternatively, implement the Shader trait and use it together with .into_effect().

Effect DSL

The DSL supports:

  • Most built-in effects (excludes: effect_fn, effect_fn_buf, glitch, offscreen_buffer, resize_area, translate, translate_buf)
  • Variable bindings
  • Method chaining
  • Complex compositions
let expr = r#"
    let duration = 300;
    fx::sequence(&[
        fx::fade_from(black, white, duration),
        fx::dissolve(duration)
    ])
"#;

🛠️ Configuration

Features

  • dsl — Effect DSL support (enabled by default)

  • sendable — Make effects Send (but not Sync)

  • std-duration — Use std::time::Duration instead of 32-bit custom type

  • web-time — WebAssembly compatibility

🤝 Contributing

Contributions welcome! Please check existing issues or create new ones to discuss changes.

📝 License

MIT License - see LICENSE for details.

Commit count: 120

cargo fmt