A complete deck
A whole video: the pitch template, renamed and extended with a slide of your own, in the sunset theme over a glow, with a footer and a slide transition between the slides. Render it with the fframes command line, or step through it in fframes Studio, which stops at the slides’ reveal times.
use fframes_kit::prelude::*;
#[derive(Debug)]struct Pitch { deck: Deck<'static>,}
impl Pitch { fn new() -> Self { let mut slides = slides::templates::pitch_deck(); slides[0].layout = SlideLayout::Title { title: "Lumen", subtitle: Some("Lighting design in an afternoon"), }; // one more slide before the closing page let team = slides::Slide { hold: 4.0, notes: Some("Who we are, in one breath each."), ..slides::Slide::new( "pitch-team", SlideLayout::FeatureCards { title: "The team", items: vec![ ("Ana", "CEO, ten years in lighting design."), ("Ben", "CTO, built rendering engines."), ("Chloe", "Design, ran a studio of twenty."), ], }, ) }; let close = slides.len() - 1; slides.insert(close, team); let deck = Deck::new(slides::themes::sunset(), slides) .backdrop(slides::Backdrop::Glow) .footer("Lumen · Seed round") .transition(Slide::default(), Timing::default()); Self { deck } }}
impl Video for Pitch { const FPS: usize = 30; const WIDTH: usize = 1920; const HEIGHT: usize = 1080;
fn duration(&self) -> Duration<'_> { Duration::Auto }
fn audio(&self) -> AudioMap<'_> { AudioMap::none() }
fn define_scenes(&self) -> Scenes<'_> { self.deck.scenes() }
fn render_frame<'a>(&'a self, frame: Frame, ctx: &FFramesContext<'a, '_>) -> Svgr<'a> { svgr!( <svg viewBox="0 0 1920 1080" width={Self::WIDTH} height={Self::HEIGHT}> {ctx.render_scenes(&frame)} </svg> ) }}
let pitch = Pitch::new();assert_eq!(pitch.deck.slides().count(), 11);// the title page has no footer; the team slide is number 10 of 11let footers: Vec<_> = pitch.deck.slides().map(|s| s.footer.and_then(|f| f.page)).collect();assert_eq!(footers[0], None);assert_eq!(footers[9], Some((10, 11)));// the presenter's scriptlet script: Vec<&str> = pitch.deck.slides().filter_map(|s| s.notes()).collect();assert_eq!(script.len(), 11);The quarterly review and the talk are built the same way:
use fframes_kit::prelude::*;
let review = Deck::new(slides::themes::paper(), slides::templates::quarterly_review()) .backdrop(slides::Backdrop::Gradient) .footer("Q3 review");let talk = Deck::new(slides::themes::midnight(), slides::templates::conference_talk()) .backdrop(slides::Backdrop::Grid) .footer("Video as code") .transition(Fade::default(), Timing::default());let minutes = |deck: &Deck| deck.slides().map(slides::Slide::seconds).sum::<f32>() / 60.0;assert!(minutes(&review) > 0.5 && minutes(&talk) > 0.5);