this repo has no description
3
fork

Configure Feed

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

✨ A better way to render only some layers

authored by

Gwenn Le Bihan and committed by
Ewen Le Bihan
7a0325a6 bbcbaef4

+75 -45
+5 -7
src/canvas.rs
··· 43 43 objects: HashMap::new(), 44 44 name: name.to_string(), 45 45 _render_cache: None, 46 + hidden: false, 46 47 }) 47 48 .collect(), 48 49 ..Self::default_settings() ··· 233 234 name: name.to_string(), 234 235 objects, 235 236 _render_cache: None, 237 + hidden: false, 236 238 } 237 239 } 238 240 ··· 267 269 name: layer_name.to_owned(), 268 270 objects, 269 271 _render_cache: None, 272 + hidden: false, 270 273 } 271 274 } 272 275 ··· 512 515 ) 513 516 } 514 517 515 - pub fn render(&mut self, layers: &Vec<&str>, render_background: bool) -> Result<String> { 518 + pub fn render(&mut self, render_background: bool) -> Result<String> { 516 519 let background_color = self.background.unwrap_or_default(); 517 520 let mut svg = svg::Document::new(); 518 521 if render_background { ··· 525 528 .set("fill", background_color.render(&self.colormap)), 526 529 ); 527 530 } 528 - for layer in self 529 - .layers 530 - .iter_mut() 531 - .filter(|layer| layers.contains(&"*") || layers.contains(&layer.name.as_str())) 532 - .rev() 533 - { 531 + for layer in self.layers.iter_mut().filter(|layer| !layer.hidden).rev() { 534 532 svg = svg.add(layer.render(self.colormap.clone(), self.cell_size, layer.object_sizes)); 535 533 } 536 534
+15 -1
src/layer.rs
··· 1 - use crate::{ColorMapping, ColoredObject, Fill, Filter, ObjectSizes, Region}; 1 + use crate::{ColorMapping, ColoredObject, Fill, Filter, ObjectSizes, Region, Toggleable}; 2 2 use std::{collections::HashMap, fmt::Display}; 3 3 4 4 #[derive(Debug, Clone, Default)] ··· 7 7 pub object_sizes: ObjectSizes, 8 8 pub objects: HashMap<String, ColoredObject>, 9 9 pub name: String, 10 + pub hidden: bool, 10 11 pub _render_cache: Option<svg::node::element::Group>, 11 12 } 12 13 ··· 17 18 objects: HashMap::new(), 18 19 name: name.to_string(), 19 20 _render_cache: None, 21 + hidden: false, 20 22 } 23 + } 24 + 25 + pub fn hide(&mut self) { 26 + self.hidden = true; 27 + } 28 + 29 + pub fn show(&mut self) { 30 + self.hidden = false; 31 + } 32 + 33 + pub fn toggle(&mut self) { 34 + self.hidden.toggle(); 21 35 } 22 36 23 37 pub fn object(&mut self, name: &str) -> &mut ColoredObject {
+10
src/lib.rs
··· 190 190 } 191 191 } 192 192 193 + trait Toggleable { 194 + fn toggle(&mut self); 195 + } 196 + 197 + impl Toggleable for bool { 198 + fn toggle(&mut self) { 199 + *self = !*self; 200 + } 201 + } 202 + 193 203 #[allow(unused)] 194 204 fn main() {}
+1 -1
src/main.rs
··· 13 13 14 14 if args.cmd_image && !args.cmd_video { 15 15 canvas = examples::dna_analysis_machine(); 16 - let rendered = canvas.render(&vec!["*"], true)?; 16 + let rendered = canvas.render(true)?; 17 17 if args.arg_file.ends_with(".svg") { 18 18 std::fs::write(args.arg_file, rendered).unwrap(); 19 19 } else {
+12 -12
src/objects.rs
··· 62 62 colormap: &ColorMapping, 63 63 id: &str, 64 64 ) -> svg::node::element::Group { 65 - let group = self.object.render(cell_size, object_sizes, id); 65 + let mut group = self.object.render(cell_size, object_sizes, id); 66 66 67 - let rendered_transforms = self 67 + match self 68 68 .transformations 69 - .render_attribute(colormap, !self.object.fillable()); 69 + .render_attribute(colormap, !self.object.fillable()) 70 + { 71 + (key, _) if key.is_empty() => (), 72 + (key, value) => group = group.set(key, value), 73 + } 70 74 71 75 let mut css = String::new(); 72 76 if !matches!(self.object, Object::RawSVG(..)) { ··· 81 85 .join(" ") 82 86 .as_ref(); 83 87 84 - group 85 - .set("style", css) 86 - .set(rendered_transforms.0, rendered_transforms.1) 88 + group.set("style", css) 87 89 } 88 90 } 89 91 ··· 177 179 fn render_fill_attribute(&self, colormap: &ColorMapping) -> (String, String) { 178 180 ( 179 181 self.first() 180 - .unwrap() 181 - .render_fill_attribute(colormap) 182 - .0 182 + .map(|v| v.render_fill_attribute(colormap).0) 183 + .unwrap_or_default() 183 184 .clone(), 184 185 self.iter() 185 186 .map(|v| v.render_fill_attribute(colormap).1.clone()) ··· 190 191 fn render_stroke_attribute(&self, colormap: &ColorMapping) -> (String, String) { 191 192 ( 192 193 self.first() 193 - .unwrap() 194 - .render_stroke_attribute(colormap) 195 - .0 194 + .map(|v| v.render_stroke_attribute(colormap).0) 195 + .unwrap_or_default() 196 196 .clone(), 197 197 self.iter() 198 198 .map(|v| v.render_stroke_attribute(colormap).1.clone())
+27 -13
src/video.rs
··· 18 18 preview, 19 19 sync::SyncData, 20 20 ui::{self, setup_progress_bar, Log as _}, 21 - Canvas, ColoredObject, Context, MidiSynchronizer, MusicalDurationUnit, Syncable, 21 + Canvas, ColoredObject, Context, LayerAnimationUpdateFunction, MidiSynchronizer, 22 + MusicalDurationUnit, Syncable, 22 23 }; 23 24 24 25 pub type BeatNumber = usize; ··· 449 450 Self { commands, ..self } 450 451 } 451 452 453 + pub fn bind_amplitude( 454 + self, 455 + layer: &'static str, 456 + stem: &'static str, 457 + update: &'static LayerAnimationUpdateFunction, 458 + ) -> Self { 459 + self.with_hook(Hook { 460 + when: Box::new(move |_, _, _, _| true), 461 + render_function: Box::new(move |canvas, context| { 462 + let amplitude = context.stem(stem).amplitude_relative(); 463 + update(amplitude, canvas.layer(layer), context.ms)?; 464 + canvas.layer(layer).flush(); 465 + Ok(()) 466 + }), 467 + }) 468 + } 469 + 452 470 pub fn total_frames(&self) -> usize { 453 471 self.fps * (self.duration_ms() + self.start_rendering_at) / 1000 454 472 } ··· 470 488 let mut rendered_frames: HashMap<usize, String> = HashMap::new(); 471 489 let progress_bar = self.setup_progress_bar(); 472 490 473 - for (frame, _, ms) in self.render_frames(&progress_bar, vec!["*"], true)? { 491 + for (frame, _, ms) in self.render_frames(&progress_bar, true)? { 474 492 rendered_frames.insert(ms, frame); 475 493 } 476 494 ··· 493 511 workers_count: usize, 494 512 preview_only: bool, 495 513 ) -> Result<()> { 496 - self.render_composition(output_file, vec!["*"], true, workers_count, preview_only) 514 + self.render(output_file, true, workers_count, preview_only) 497 515 } 498 516 499 517 pub fn render_layers_in(&self, output_directory: String, workers_count: usize) -> Result<()> { ··· 503 521 .iter() 504 522 .map(|l| vec![l.name.as_str()]) 505 523 { 506 - self.render_composition( 524 + self.render( 507 525 format!("{}/{}.mov", output_directory, composition.join("+")), 508 - composition, 509 526 false, 510 527 workers_count, 511 528 false, ··· 518 535 pub fn render_frames( 519 536 &self, 520 537 progress_bar: &ProgressBar, 521 - composition: Vec<&str>, 522 538 render_background: bool, 523 539 ) -> Result<Vec<(String, usize, usize)>> { 524 540 let mut context = Context { ··· 611 627 } 612 628 613 629 if context.frame != previous_rendered_frame { 614 - let rendered = canvas.render(&composition, render_background)?; 630 + let rendered = canvas.render(render_background)?; 615 631 616 632 previous_rendered_beat = context.beat; 617 633 previous_rendered_frame = context.frame; ··· 627 643 ui::setup_progress_bar(self.total_frames() as u64, "Rendering") 628 644 } 629 645 630 - pub fn render_composition( 646 + pub fn render( 631 647 &self, 632 648 output_file: String, 633 - composition: Vec<&str>, 634 649 render_background: bool, 635 650 workers_count: usize, 636 651 _preview_only: bool, ··· 651 666 self.progress_bar.set_prefix("Rendering"); 652 667 self.progress_bar.set_message(""); 653 668 654 - for (frame, no, ms) in 655 - self.render_frames(&self.progress_bar, composition, render_background)? 656 - { 669 + for (frame, no, ms) in self.render_frames(&self.progress_bar, render_background)? { 657 670 frames_to_write.push((frame, no, ms)); 658 671 } 659 672 ··· 697 710 frames_output_directory, 698 711 aspect_ratio, 699 712 resolution, 700 - ).unwrap(); 713 + ) 714 + .unwrap(); 701 715 progress_bar.inc(1); 702 716 } 703 717 })
+5 -11
src/web.rs
··· 65 65 66 66 #[wasm_bindgen] 67 67 pub fn render_canvas_into(selector: String) -> () { 68 - let svgstring = canvas().render(&vec!["*"], false).unwrap_throw(); 68 + let svgstring = canvas().render(false).unwrap_throw(); 69 69 append_new_div_inside(svgstring, selector) 70 70 } 71 71 72 72 #[wasm_bindgen] 73 73 pub fn render_canvas_at(selector: String) -> () { 74 - let svgstring = canvas().render(&vec!["*"], false).unwrap_throw(); 74 + let svgstring = canvas().render(false).unwrap_throw(); 75 75 replace_content_with(svgstring, selector) 76 76 } 77 77 ··· 135 135 } 136 136 137 137 #[wasm_bindgen] 138 - pub fn render_canvas(layers_pattern: Option<String>, render_background: Option<bool>) -> () { 138 + pub fn render_canvas(render_background: Option<bool>) -> () { 139 139 canvas() 140 - .render( 141 - &match layers_pattern { 142 - Some(ref pattern) => vec![pattern], 143 - None => vec!["*"], 144 - }, 145 - render_background.unwrap_or(false), 146 - ) 140 + .render(render_background.unwrap_or(false)) 147 141 .unwrap_throw(); 148 142 } 149 143 ··· 214 208 #[wasm_bindgen] 215 209 impl LayerWeb { 216 210 pub fn render(&self) -> String { 217 - canvas().render(&vec![&self.name], false).unwrap_throw() 211 + canvas().render(false).unwrap_throw() 218 212 } 219 213 220 214 pub fn render_into(&self, selector: String) -> () {