Skip to content

Commit

Permalink
add more demos
Browse files Browse the repository at this point in the history
  • Loading branch information
Wayoung7 committed Mar 15, 2024
1 parent 5191e02 commit 7b04708
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 39 deletions.
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
![demo_0](gif/demo_0.gif)
<h1 align="center">
<br>
Firework-rs
<br>
</h1>

Firework-rs is a cross-platform ascii-art firework simulator in terminal. Run the binary or use the library to create your own firework, and just enjoy the beautiful fireworks in your terminal!

## Features

- Colorful ASCII art firework
- Smooth animation
- Customizable fireworks
- Simple particle system letting you make fireworks but not only fireworks

## Try Out a Demo

Install [rust](https://www.rust-lang.org/tools/install) if you havn't.
Expand All @@ -15,16 +22,18 @@ Then, simply run the following commands:
```
git clone https://github.com/Wayoung7/firework-rs.git
cd firework-rs
cargo run --release -- --demo 1
cargo run --release -- --demo 0
```

or to install globally on your computer:

```
cargo install firework-rs
firework --demo 1
firework --demo 0
```

The binary now has **4 demos**, from **0** to **3**.

## Exit

To exit the program, simply press `ESC`
Expand Down Expand Up @@ -163,11 +172,11 @@ cargo run --example <EXAMPLE-NAME>

fountain

![fountain](gif/fountain.GIF)
![fountain](gif/fountain.gif)

vortex

![vortex](gif/vortex.GIF)
![vortex](gif/vortex.gif)

heart

Expand All @@ -184,7 +193,7 @@ This crate uses [crossterm](https://github.com/crossterm-rs/crossterm) as backen

This crate supports all UNIX terminals and Windows terminals down to Windows 7. however, not all of the terminals have been tested and has good viusal quality.

It is recommanded to use terminal that has GPU rendering acceleration, like [Kitty](https://github.com/kovidgoyal/kitty) (which I use) and [Alacritty](https://github.com/alacritty/alacritty). Make sure your terminal does not have extra color theme or adjustment. If you enable gradient in the program, make sure the terminal window is **non-transparent** and has **black background**.
It is recommanded to use terminal that has GPU rendering acceleration, like [Kitty](https://github.com/kovidgoyal/kitty) and [Alacritty](https://github.com/alacritty/alacritty). Make sure your terminal does not have extra color theme or adjustment. If you enable gradient in the program, make sure the terminal window is **non-transparent** and has **black background**.

## Help

Expand Down
Binary file added gif/demo_0.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed gif/fountain.GIF
Binary file not shown.
Binary file added gif/fountain.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed gif/heart.GIF
Binary file not shown.
Binary file modified gif/heart.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed gif/vortex.GIF
Binary file not shown.
Binary file added gif/vortex.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 28 additions & 24 deletions src/bin/firework/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
mod args;

use std::{
fs,
io::{stdout, Result, Write},
io::{stdout, Result},
thread::sleep,
time::{Duration, Instant, SystemTime},
time::{Duration, SystemTime},
};

use args::Cli;
Expand All @@ -14,40 +13,45 @@ use crossterm::{
event::{self, KeyCode},
execute, terminal,
};
use firework_rs::demo::{demo_firework_1, demo_firework_2, demo_firework_comb_1};
use firework_rs::demo::{demo_firework_2, demo_firework_comb_0, demo_firework_comb_1};
use firework_rs::fireworks::FireworkManager;
use firework_rs::term::Terminal;
use glam::Vec2;

fn main() -> Result<()> {
let mut is_running = true;
let cli = Cli::parse();
let mut stdout = stdout();
let (_width, _height) = terminal::size()?;
let mut is_running = true;
let mut fm = match cli.demo {
0 => FireworkManager::default().add_fireworks(demo_firework_comb_0(
Vec2::new(_width as f32 / 4., _height as f32 / 2.),
Duration::from_secs_f32(0.7),
cli.gradient,
)),
1 => FireworkManager::default().add_fireworks(demo_firework_comb_1(
Vec2::new(_width as f32 / 4., 66.),
Duration::from_secs_f32(0.2),
cli.gradient,
)),
2 => FireworkManager::default().add_firework(demo_firework_2(
Vec2::new(_width as f32 / 4., _height as f32 / 2.),
Duration::from_secs_f32(0.7),
cli.gradient,
)),
_ => {
println!("Demo number error\n");
is_running = false;
FireworkManager::default()
}
};
fm.set_enable_loop(cli.looping);

let mut stdout = stdout();
terminal::enable_raw_mode()?;
execute!(stdout, terminal::EnterAlternateScreen, cursor::Hide)?;

let mut time = SystemTime::now();
let mut term = Terminal::default();
let mut fm = FireworkManager::default().add_fireworks(demo_firework_comb_1(
Vec2::new(30., 66.),
Duration::from_secs_f32(0.2),
cli.gradient,
));
// fm.set_enable_loop(cli.looping);
// .add_firework(demo_firework_1(
// Vec2::new(20., 15.),
// Duration::from_secs_f32(1.),
// ))
// .add_firework(demo_firework_2(
// Vec2::new(40., 25.),
// Duration::from_secs_f32(1.3),
// ))
// .add_firework(demo_firework_1(
// Vec2::new(15., 45.),
// Duration::from_secs_f32(2.),
// ));

while is_running {
if event::poll(Duration::ZERO)? {
Expand Down
157 changes: 151 additions & 6 deletions src/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use rand::{seq::IteratorRandom, thread_rng, Rng};

use crate::{
fireworks::{Firework, FireworkConfig},
particle::{Particle, ParticleConfig},
particle::ParticleConfig,
utils::{
explosion_gradient_1, explosion_gradient_2, gen_points_circle, gen_points_circle_normal,
linear_gradient_1,
explosion_gradient_1, explosion_gradient_2, explosion_gradient_3, gen_points_circle,
gen_points_circle_normal, linear_gradient_1,
},
};

Expand All @@ -20,12 +20,12 @@ pub fn demo_firework_1(center: Vec2, spawn_after: Duration, enable_gradient: boo
(206, 32, 41),
];
let mut particles = Vec::new();
for v in gen_points_circle(300, 45).iter() {
for v in gen_points_circle_normal(280., 45).iter() {
particles.push(ParticleConfig::new(
center,
*v,
thread_rng().gen_range(23..43),
Duration::from_secs_f32(thread_rng().gen_range(2.5..4.5)),
thread_rng().gen_range(23..27),
Duration::from_secs_f32(thread_rng().gen_range(2.1..2.7)),
*colors.iter().choose(&mut thread_rng()).unwrap(),
));
}
Expand Down Expand Up @@ -68,6 +68,117 @@ pub fn demo_firework_2(center: Vec2, spawn_after: Duration, enable_gradient: boo
}
}

pub fn demo_firework_3(center: Vec2, spawn_after: Duration, enable_gradient: bool) -> Firework {
let colors = vec![
(242, 233, 190),
(226, 196, 136),
(149, 202, 176),
(26, 64, 126),
];
let mut particles = Vec::new();
for v in gen_points_circle_normal(350., 135).iter() {
particles.push(ParticleConfig::new(
center,
*v,
thread_rng().gen_range(23..43),
Duration::from_secs_f32(thread_rng().gen_range(3.5..5.0)),
*colors.iter().choose(&mut thread_rng()).unwrap(),
));
}
let mut config = FireworkConfig::default()
.with_gradient_scale(explosion_gradient_1)
.with_ar_scale(0.18)
.with_gravity_scale(0.7);
config.set_enable_gradient(enable_gradient);
Firework {
init_time: SystemTime::now(),
spawn_after,
center,
particles,
config,
..Default::default()
}
}

pub fn demo_firework_4(center: Vec2, spawn_after: Duration, enable_gradient: bool) -> Firework {
let colors = vec![(242, 233, 190), (226, 196, 136), (255, 248, 253)];
let mut particles = Vec::new();
for v in gen_points_circle_normal(350., 25).iter() {
particles.push(ParticleConfig::new(
center,
*v,
thread_rng().gen_range(20..33),
Duration::from_secs_f32(thread_rng().gen_range(3.5..5.0)),
*colors.iter().choose(&mut thread_rng()).unwrap(),
));
}
let mut config = FireworkConfig::default()
.with_gradient_scale(explosion_gradient_1)
.with_gravity_scale(0.3);
config.set_enable_gradient(enable_gradient);
Firework {
init_time: SystemTime::now(),
spawn_after,
center,
particles,
config,
..Default::default()
}
}

pub fn demo_firework_5(center: Vec2, spawn_after: Duration, enable_gradient: bool) -> Firework {
let colors = vec![(152, 186, 227), (54, 84, 117), (21, 39, 60)];
let mut particles = Vec::new();
for v in gen_points_circle_normal(450., 80).iter() {
particles.push(ParticleConfig::new(
center,
*v,
thread_rng().gen_range(33..43),
Duration::from_secs_f32(thread_rng().gen_range(3.5..5.0)),
*colors.iter().choose(&mut thread_rng()).unwrap(),
));
}
let mut config = FireworkConfig::default()
.with_gradient_scale(explosion_gradient_3)
.with_gravity_scale(1.4);
config.set_enable_gradient(enable_gradient);
Firework {
init_time: SystemTime::now(),
spawn_after,
center,
particles,
config,
..Default::default()
}
}

pub fn demo_firework_6(center: Vec2, spawn_after: Duration, enable_gradient: bool) -> Firework {
let colors = vec![(242, 233, 190), (226, 196, 136), (255, 248, 253)];
let mut particles = Vec::new();
for v in gen_points_circle_normal(350., 35).iter() {
particles.push(ParticleConfig::new(
center,
*v,
thread_rng().gen_range(20..23),
Duration::from_secs_f32(thread_rng().gen_range(3.5..4.0)),
*colors.iter().choose(&mut thread_rng()).unwrap(),
));
}
let mut config = FireworkConfig::default()
.with_gradient_scale(explosion_gradient_1)
.with_ar_scale(0.19)
.with_gravity_scale(0.1);
config.set_enable_gradient(enable_gradient);
Firework {
init_time: SystemTime::now(),
spawn_after,
center,
particles,
config,
..Default::default()
}
}

pub fn demo_firework_comb_1(
start: Vec2,
spawn_after: Duration,
Expand Down Expand Up @@ -130,3 +241,37 @@ pub fn demo_firework_comb_1(
},
]
}

pub fn demo_firework_comb_0(
center: Vec2,
spawn_after: Duration,
enable_gradient: bool,
) -> Vec<Firework> {
let mut res = Vec::new();
res.push(demo_firework_3(
center + Vec2::new(-5., -19.),
spawn_after,
enable_gradient,
));
res.push(demo_firework_4(
center + Vec2::new(-30., 0.),
spawn_after + Duration::from_secs_f32(0.4),
enable_gradient,
));
res.push(demo_firework_5(
center + Vec2::new(12., 0.),
spawn_after + Duration::from_secs_f32(1.6),
enable_gradient,
));
res.push(demo_firework_1(
center + Vec2::new(-9., 7.),
spawn_after + Duration::from_secs_f32(2.),
enable_gradient,
));
res.push(demo_firework_6(
center + Vec2::new(24., -11.),
spawn_after + Duration::from_secs_f32(2.3),
enable_gradient,
));
res
}
5 changes: 2 additions & 3 deletions src/particle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::{collections::HashMap, time::Duration};
use std::time::Duration;

use glam::Vec2;
use rand::{seq::IteratorRandom, thread_rng};

use crate::{fireworks::FireworkConfig, utils::distance_squared};
use crate::fireworks::FireworkConfig;

/// The struct represents the states in a `Particle`'s lifetime
///
Expand Down
1 change: 1 addition & 0 deletions src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct Char {
pub color: style::Color,
}

#[allow(unused)]
impl Char {
/// Create a new `Char`
fn new(text: char, color: style::Color) -> Self {
Expand Down
11 changes: 11 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ pub fn explosion_gradient_2(x: f32) -> f32 {
}
}

/// A sample function defining the gradient of the `Particle`
///
/// The visual effect is similar to an explosion, darkar than `explosion_gradient_1`
pub fn explosion_gradient_3(x: f32) -> f32 {
if x < 0.087 {
150. * x.powi(2) * 0.6
} else {
(-0.8 * x + 1.2) * 0.6
}
}

/// A sample function defining the gradient of the `Particle`
///
/// Linear gradient
Expand Down

0 comments on commit 7b04708

Please sign in to comment.