use nannou::{prelude::*, color::Alpha}; use noise::{Fbm, NoiseFn}; const WIDTH: f32 = 512.0; #[derive(Debug)] struct Model { noise: Fbm, } fn main() { nannou::app(model).run(); } fn model(app: &App) -> Model { app.set_loop_mode(LoopMode::Wait); let _window = app .new_window() .size(WIDTH as u32, WIDTH as u32) .view(view) .key_pressed(key_pressed) .build() .unwrap(); Model { noise: Fbm::new(), } } fn view(app: &App, model: &Model, frame: Frame) { let draw = app .draw() .scale_y(-1.0) .translate(vec3(WIDTH / -2.0, WIDTH / -2.0, 0.0)); draw.background().color(MINTCREAM); let block_size: usize = 32; let x_step = 0.01; let y_step = 0.002; let line_color = Alpha { color: LIGHTSALMON, alpha: 0.3 }; for x in (block_size..(frame.rect().w() as usize - block_size)).step_by(block_size / 8) { for y in (block_size..(frame.rect().h() as usize - block_size)).step_by(block_size / 8) { let half = (block_size / 2) as f32; let v1 = vec2(x as f32, y as f32); let noise = model.noise.get([(v1.x * x_step) as f64, (v1.y * y_step) as f64]) as f32; let v2 = v1 + vec2(0.0, half * map_range(noise, -1.0, 1.0, 0.0, 2.0)).rotate(noise * TAU); draw.line().weight(1.0).points(v1, v2).color(line_color); } } draw.to_frame(app, &frame).unwrap(); } fn captured_frame_path(app: &App) -> std::path::PathBuf { // Create a path that we want to save this frame to. app.project_path() .expect("failed to locate `project_path`") // Capture all frames to a directory called `//screenshots/`. .join("screenshots") .join(app.exe_name().unwrap()) // Name each file after the number of the frame. .join(format!("{:03}", app.elapsed_frames())) // The extension will be PNG. We also support tiff, bmp, gif, jpeg, webp and some others. .with_extension("png") } fn key_pressed(app: &App, _model: &mut Model, key: Key) { if key == Key::S { let file_path = captured_frame_path(app); println!("Saving to {:?}…", file_path); app.main_window().capture_frame(file_path); } }