# Time containers and fades

> Gallery scenes: Sequence, Series, Loop, Freeze, FadeIn, FadeOut, Fill.

Page: https://fframes-kit.pages.dev/docs/basics/time-containers-and-fades/

| Component | Props | What it does |
| --- | --- | --- |
| `Sequence` | `from`, `duration: Option<f32>`, `children` | shows children from `from` seconds, for `duration` or until the parent ends |
| `Series` | `items: Vec<(f32, Children)>`, `overlap` | children back to back, each for its seconds; `overlap` starts each one earlier |
| `Loop` | `duration`, `times: Option<usize>`, `children` | repeats children every `duration` seconds |
| `Freeze` | `at`, `children` | children frozen at `at` seconds of their time |
| `Fill` | `background: Option<Color>`, `children` | full-canvas group (Remotion's `AbsoluteFill`) |
| `FadeIn` | `shift`, `delay`, `run_time`, `rate_func` | `Enter`: fades in while moving by `shift` into place; `fade.apply(ui, content)` |
| `FadeOut` | `shift`, `delay`, `run_time`, `rate_func` | `Exit`: fades out before the end of `ui.duration` (`delay` seconds before it) |

Gallery scenes: `Sequence`, `Series`, `Loop`, `Freeze`, `FadeIn`, `FadeOut`, `Fill`.

Gallery clip of `Sequence`: https://fframes-kit.pages.dev/media/scenes/Sequence-c55dbbba.mp4

Gallery clip of `Series`: https://fframes-kit.pages.dev/media/scenes/Series-29964794.mp4

Gallery clip of `Loop`: https://fframes-kit.pages.dev/media/scenes/Loop-482b7757.mp4

Gallery clip of `Freeze`: https://fframes-kit.pages.dev/media/scenes/Freeze-67701e3c.mp4

Gallery clip of `FadeIn`: https://fframes-kit.pages.dev/media/scenes/FadeIn-0de626b6.mp4

Gallery clip of `FadeOut`: https://fframes-kit.pages.dev/media/scenes/FadeOut-c9c65098.mp4

Gallery clip of `Fill`: https://fframes-kit.pages.dev/media/scenes/Fill-d69f144a.mp4

Repeat a local animation, or hold it at a particular local time:

```rust
use fframes_kit::prelude::*;

fn timed<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
    let sequence = ui.show(Sequence {
        from: 0.5, duration: Some(1.0),
        children: children(|ui| ui.show(Dot { ..ui.defaults() })),
    });
    let series = ui.show(Series {
        items: vec![
            (1.0, children(|ui| ui.show(Circle { ..ui.defaults() }))),
            (1.0, children(|ui| ui.show(Square { ..ui.defaults() }))),
        ],
        overlap: 0.0,
    });
    let repeated = ui.show(Loop {
        duration: 2.0, times: Some(3),
        children: children(|ui| ui.show(Circle { enter: Some(Create::default().into()), ..ui.defaults() })),
    });
    let frozen = ui.show(Freeze {
        at: 0.5,
        children: children(|ui| ui.show(Square { enter: Some(Create::default().into()), ..ui.defaults() })),
    });
    let fill = ui.show(Fill {
        background: Some(ui.theme.colors.background),
        children: children(|ui| ui.show(Circle { cx: 1200.0, cy: 540.0, radius: 80.0, ..ui.defaults() })),
    });
    svgr!(<g>{fill}{sequence}{series}{repeated}{frozen}</g>)
}
```

`RateFunc` has Manim's names: `Smooth` (default), `Linear`, `RushInto`, `RushFrom`,
`ThereAndBack`, `DoubleSmooth`, plus `Easing(fframes::animation::Easing)` for CSS curves and
springs. `motion` has `progress`, `clamp01`, `lerp`, `stagger(i, step)`, `spring`, `hash`,
`noise`, the easing curves `expo_in`, `expo_out`, `cubic_in_out` and `quart_out` on `0..=1`,
`timecode(frames, fps)` (`hh:mm:ss:ff`, an error for 0 fps) and `thousands(n)` (`12,480`).

```rust
use fframes_kit::prelude::*;

assert_eq!(motion::progress(0.5, 0.0, 2.0), 0.25);
assert_eq!(RateFunc::Linear.apply(0.3, 1.0), 0.3);
assert_eq!(motion::noise(7, 1.25), motion::noise(7, 1.25));
assert_eq!(motion::timecode(3_725, 60).unwrap(), "00:01:02:05");
assert_eq!(motion::thousands(12_480), "12,480");
```

For a video cut to music, `Beat { period, downbeat }` is the beat grid: beat 0 is the
first downbeat, at `downbeat` seconds, and beats are `period` seconds apart. It stores the
period rather than the BPM, so a measured period is used exactly; `Beat::from_bpm(bpm,
downbeat)` makes one from a tempo. `time(beat)` and `frame(beat, fps)` place things on the
grid (frames are rounded, so scene edges never drift), `beat_at(seconds)` reads it back, and
`snap(beats)` and `soft(beats)` are springs released `beats` ago (their `(stiffness,
damping)` are the fields `snap_spring` (320, 22) and `soft_spring` (170, 15)).
`Beat::pulse(beat, sharpness)` is 1 on every beat and decays until the next.
Gallery scene: `Beat`.

Gallery clip of `Beat`: https://fframes-kit.pages.dev/media/scenes/Beat-733c40f5.mp4

```rust
use fframes_kit::prelude::*;

const GRID: Beat = Beat::new(0.5, 2.0); // 120 BPM, first downbeat at 2 s

assert_eq!(GRID.time(4.0), 4.0);
assert_eq!(GRID.frame(4.0, 30), 120);
assert_eq!(GRID.beat_at(3.0), 2.0);
assert_eq!(Beat::pulse(3.0, 8.0), 1.0);
```

## API

Components are plain structs. Set the fields you need and fill the rest with `..ui.defaults()`: the defaults below come from the current theme (`theme.` values are fields of `Theme`).

### Sequence

Shows its children from `from` seconds on, for `duration` seconds or until the parent ends. Inside, time starts at 0 and `ui.duration` is the sequence's length.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `from` | `f32` | `0.0` | Start in the parent's local seconds. |
| `duration` | `Option<f32>` | `None` | Length in seconds; `None` runs until the parent ends. |
| `children` | `Children` | `no_children()` | What it shows; a closure taking the `Ui`, whose time starts at 0 at `from`. |

[Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/time.rs#L27)

### Series

Children one after the other, each for its own number of seconds. Each item starts `overlap` seconds before the previous one ends, so both show during the overlap.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `items` | `Vec<(f32, Children)>` | — | `(seconds, children)` in play order. |
| `overlap` | `f32` | — | Seconds each item overlaps the one before it; 0 plays them back to back. |

[Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/time.rs#L65)

### Loop

Repeats its children every `duration` seconds, `times` times or forever (`None`).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `duration` | `f32` | `1.0` | Seconds one repeat lasts. |
| `times` | `Option<usize>` | `None` | How many repeats before it stops showing; `None` for forever. |
| `children` | `Children` | `no_children()` | What it repeats; a closure taking the `Ui` whose time restarts at 0 each repeat. |

[Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/time.rs#L110)

### Freeze

Shows its children frozen at `at` seconds of their local time.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `at` | `f32` | `0.0` | Seconds of the children's local time to show, whatever the frame. |
| `children` | `Children` | `no_children()` | What it draws, frozen at `at`; a closure taking the `Ui`. |

[Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/time.rs#L156)

### Fill

A group covering the whole canvas, optionally on a background colour (Remotion's `AbsoluteFill`).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `background` | `Option<Color>` | `None` | Colour painted behind the children; `None` for none. |
| `children` | `Children` | `no_children()` | What it draws over the background, a closure taking the `Ui`. |

[Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/time.rs#L185)
