This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.6 kB View raw
1use anyhow::Result; 2use rand::{Rng, rngs::SmallRng, seq::IteratorRandom}; 3use shapemaker::CornerPoint as P; 4use shapemaker::*; 5 6use crate::State; 7 8pub fn backbone() -> Scene<State> { 9 Scene::<State>::new("backbone") 10 .init(&|canvas, ctx| { 11 canvas.clear(); 12 13 canvas.colormap = ColorMapping { 14 black: "#000000".to_string(), 15 white: "#FFFFFF".to_string(), 16 purple: "#da40f5".to_string(), 17 ..Default::default() 18 }; 19 20 canvas.set_grid_size(16, 10); 21 canvas.set_background(Black); 22 canvas.object_sizes.dot_radius = 7.5; 23 24 iterate(&mut ctx.extra.rng, canvas)?; 25 Ok(()) 26 }) 27 // .each_n_frame(3, &|canvas, ctx| { 28 // canvas.clear(); 29 // iterate(&mut ctx.extra.rng, canvas)?; 30 // Ok(()) 31 // }) 32 .on_note("anchor kick", &|canvas, ctx| { 33 canvas.clear(); 34 iterate(&mut ctx.extra.rng, canvas)?; 35 36 let world = canvas.world_region.clone(); 37 let flickers = canvas.layer("flickers")?; 38 39 let point = world.iter().choose(&mut ctx.extra.rng).unwrap(); 40 41 flickers.tag_objects("rotate", |id, _| { 42 id == &format!("crosses-SWNE-{point}") 43 || id == &format!("crosses-NWSE-{point}") 44 }); 45 46 ctx.animate(200, &move |t, canvas, _| { 47 canvas 48 .layer("flickers")? 49 .objects_with_tag("rotate") 50 .for_each(|(_, obj)| { 51 obj.recolor(Cyan); 52 obj.set_rotation(Angle::from_degrees(t * 90.0)); 53 }); 54 55 Ok(()) 56 }); 57 58 Ok(()) 59 }) 60 .dump_frame_when(&|_, ctx, _, _| match ctx.since_scene_start() { 61 Some(t) => t.as_millis() == 500, 62 None => false, 63 }) 64} 65 66fn iterate(rng: &mut SmallRng, canvas: &mut Canvas) -> Result<()> { 67 // let mut rng = canvas.rng.clone(); 68 let world = canvas.world_region.clone(); 69 70 let grid_thickness = 2.0; 71 72 for point in 73 Region::from((world.topleft(), world.topright().translated(1, 1))) 74 { 75 canvas.root().set( 76 format!("grid-rows-{point}"), 77 Shape::Line( 78 P(point.x(), world.topleft().y()), 79 P(point.x(), world.bottomleft().y() + 1), 80 grid_thickness * 0.75, 81 ) 82 .filled(White.translucent(0.05 + rng.random_range(0.0..0.3))), 83 ); 84 } 85 86 for point in 87 Region::from((world.topleft(), world.bottomleft().translated(1, 1))) 88 { 89 canvas.root().set( 90 format!("grid-cols-{point}"), 91 Shape::Line( 92 P(world.topleft().x(), point.y()), 93 P(world.bottomright().x() + 1, point.y()), 94 grid_thickness * 0.75, 95 ) 96 .filled(White.translucent(0.005 + rng.random_range(0.0..0.3))), 97 ); 98 } 99 100 let occlusions = canvas.layer_or_empty("occlusions"); 101 102 for point in world.enlarged(1, 1) { 103 occlusions.set( 104 format!("occlusion-{point}"), 105 Shape::Dot(point).colored(Color::Black), 106 ); 107 } 108 109 let flickers = canvas.layer_or_empty("flickers"); 110 111 for point in world { 112 flickers.set( 113 format!("crosses-SWNE-{point}"), 114 Shape::Line(point, point.translated(1, 1), grid_thickness) 115 .colored(Color::Purple) 116 .flickering(rng, 0.25) 117 .clipped_to((point, point)), 118 ); 119 flickers.set( 120 format!("crosses-NWSE-{point}"), 121 Shape::Line( 122 point.translated(0, 1), 123 point.translated(1, 0), 124 grid_thickness, 125 ) 126 .colored(Color::Purple) 127 .flickering(rng, 0.25) 128 .clipped_to((point, point)), 129 ); 130 } 131 132 let flickers_occlusions = canvas.layer_or_empty("flickers_occlusions"); 133 flickers_occlusions.object_sizes.dot_radius = 10.0; 134 135 for point in world.enlarged(1, 1) { 136 flickers_occlusions.set( 137 format!("crosses-occlusions-{point}"), 138 Shape::Dot(point).colored(Color::Black), 139 ) 140 } 141 142 canvas.reorder_layers(vec![ 143 "flickers_occlusions", 144 "flickers", 145 "occlusions", 146 "root", 147 ]); 148 149 Ok(()) 150}